Frontend Development 8 min read

Introduction to PostCSS and Developing Custom Plugins

This article introduces PostCSS, explains its role in transforming CSS via JavaScript plugins, demonstrates how to integrate it with tools like Webpack and its JavaScript API, and provides a step‑by‑step guide for creating a simple PostCSS plugin that doubles pixel values, including handling of Less syntax.

Qunar Tech Salon
Qunar Tech Salon
Qunar Tech Salon
Introduction to PostCSS and Developing Custom Plugins

Getting Started with PostCSS

CSS is a core part of web development, but browser compatibility issues have led to preprocessors such as Sass, Less, and Stylus. PostCSS is defined as a tool for transforming CSS with JavaScript; it parses CSS into an abstract syntax tree (AST) and lets plugins manipulate that tree before converting it back to plain CSS.

What PostCSS Can Do

There are over 200 PostCSS plugins. Some popular ones include:

autoprefixer – adds vendor prefixes based on caniuse data.

postcss-preset-env – enables the latest CSS features while maintaining compatibility.

postcss-modules – provides scoped class names.

precss – adds Sass‑like syntax (variables, nesting, mixins).

stylelint – lints CSS for syntax errors.

More plugins can be found at the official list .

Using PostCSS with Build Tools

PostCSS can be combined with bundlers such as Webpack, Gulp, Grunt, or Rollup. Below is a minimal Webpack configuration that loads PostCSS:

module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/,
        exclude: /node_modules/,
        use: [
          { loader: 'style-loader', options: { importLoaders: 1 } },
          { loader: 'css-loader' },
          { loader: 'postcss-loader' }
        ]
      }
    ]
  }
};

PostCSS JavaScript API

const autoprefixer = require('autoprefixer');
const postcss = require('postcss');
const precss = require('precss');
const css = `
.test {
  color: #fff;
}`;
postcss([precss, autoprefixer])
  .process(css, { from: 'src/app.css', to: 'dest/app.css' })
  .then(result => {
    console.log(result.css);
  });

Building a PostCSS Plugin from Scratch

Understanding the AST

Before writing a plugin, you need to understand the AST that PostCSS generates. For example, the CSS rule body { margin: 0; } is represented as a JSON object with a root node containing a rule node, which in turn contains a declaration node for the margin property.

Key AST node types are root , rule , decl , atrule , and comment . Traversal methods include .walk() , .walkAtRules() , .walkRules() , and .walkComments() . See the PostCSS API documentation for details.

Creating a Simple Plugin

The following plugin doubles every pixel value found in declarations:

const postcss = require('postcss');
const postcssPluginParseMargin = postcss.plugin('postcss-parse-margin', function () {
  return function (root) {
    root.walkDecls(function (decl) {
      decl.value = decl.value.replace(/(\d*\.?\d+)\s*px/, function (match, numStr) {
        return Number(numStr) * 2 + 'px';
      });
    });
  };
});

const css = `
  .test {
    font-size: 2.5px;
  }
`;
postcss([postcssPluginParseMargin])
  .process(css)
  .then(res => {
    console.log(res.css);
  });

This plugin uses root.walkDecls to iterate over all declaration nodes, replaces pixel values with their doubled equivalents, and outputs the transformed CSS.

Real‑World Problem: Using PostCSS to Process Less Syntax

Less is a CSS preprocessor with features like variables and mixins. To process Less with PostCSS without a double‑parse step, you can use postcss-less-engine , which converts a Less AST directly into a PostCSS AST. The original engine is outdated for Less 3.x, but a fork postcss-less-engine-latest works with newer versions.

const postcss = require('postcss');
const postCssLessEngine = require('postcss-less-engine');
const css = `
@color: red;
.test { color: @color; }
`;
postcss([postCssLessEngine()])
  .process(css, { parser: postCssLessEngine.parser })
  .then(result => {
    console.log(result.css);
  });

If you only need partial Less support, you can write a custom PostCSS plugin that recognizes Less constructs (using postcss-less for parsing) and then transforms them as needed.

JavaScriptPluginWebpackCSSPostCSSLess
Qunar Tech Salon
Written by

Qunar Tech Salon

Qunar Tech Salon is a learning and exchange platform for Qunar engineers and industry peers. We share cutting-edge technology trends and topics, providing a free platform for mid-to-senior technical professionals to exchange and learn.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.