What is PostCSS?

PostCSS calls itself a "tool for transforming CSS with JavaScript". So, in short, PostCSS can help you by taking your Sass-like CSS input and transforms it to clean CSS. But in contrast to Sass, PostCSS is pretty modular, so you can just plug in what you really need.

Even you didn't notice; I am pretty sure that you used PostCSS before. The best known PostCSS plugin is Autoprefixer. There are plenty of other plugins available. So let's take a look at the most popular ones and how to get started in no time.

Set up initial npm project

To get PostCSS running via CLI or npm script, we first need to create a project! Run the following commands on your terminal.

$ mkdir pcssdemo pcssdemo/src pcssdemo/assets
$ cd pcssdemo
$ touch index.html postcss.config.js src/main.scss
$ npm init -y

Now your folder structure should look like this:

├── assets
├── index.html
├── package.json
├── postcss.config.js
└── src
    └── main.scss

Install PostCSS

First of all, let's install PostCSS and the CLI as dev dependencies so that you can run it from any npm script.

$ npm i -D postcss postcss-cli

Now you can use the CLI like this:

$ npx postcss [input.css] [OPTIONS] [-o|—output output.css] [—watch|-w]

Now we're gonna write some CSS to our src/main.scss, add some HTML to our index.html, and open our package.json to add the css script!

// src/main.scss
html,
body {
  margin: 0;
  padding: 0;
}

body {
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji',
    'Segoe UI Emoji', 'Segoe UI Symbol';
  background-color: #011628;
  width: 100vw;
  height: 100vh;
  display: grid;
  place-items: center;
}

h1 {
  color: #f6f7f8;
}
<!-- index.html -->
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>PostCSS Demo</title>
    <link rel="stylesheet" href="./assets/main.css" />
  </head>
  <body>
        <h1>Welcome to PostCSS</h1>
  </body>
</html>
// package.json
{
  "scripts": {
    "css": "npx postcss src/main.scss -o assets/main.css --no-map --verbose"
  },
}

Ok, now cross your fingers and let's take a look if everything works as expected.

$ npm run css

> pcssdemo@1.0.0 css /Users/me/pcssdemo
> postcss src/main.scss -o assets/main.css --no-map --verbose

Processing src/main.scss...
You did not set any plugins, parser, or stringifier. Right now, PostCSS does nothing. Pick plugins for your case on https://www.postcss.parts/ and use them in postcss.config.js.
Finished src/main.scss in 9.4 ms

Nothing broke, but also nothing happened. We need to add some plugins to have fun!

Add Nesting plugin

My favorite Sass feature is definitely nesting! To add this feature, we change the CSS a little bit, install the postcss-nested plugin, and add this plugin to our postcss.config.js:

// src/main.scss
// ...
// ...
h1 {
  color: #f6f7f8;

  &::after {
    content: '👋';
  }
}
$ npm i --save-dev postcss-nested
// postcss.config.js
module.exports = {
  plugins: [require('postcss-nested')]
};
$ npm run css

> pcssdemo@1.0.0 css /Users/me/pcssdemo
> postcss src/main.scss -o assets/main.css --no-map --verbose

Processing src/main.scss...
Finished src/main.scss in 72 ms

Looks good! PostCSS ran pretty fast without any errors, and if you open the demo HTML file, you'll see a beautiful waving hands emoji.

@import "newplugin.css"

Another great Sass feature is the possibility to import other CSS files, which will be inlined.

$ npm I --save-dev postcss-import

We install this plugin as a dev dependency and add it to our plugins array in the postcss.config.js. But be careful:

This plugin should probably be used as the first plugin of your list. This way, other plugins will work on the AST as if there were only a single file to process, and will probably work as you can expect.

In short: always put the postcss-import plugin to the beginning of your array!

// postcss.config.js
module.exports = {
  plugins: [require('postcss-import'), require('postcss-nested')]
};

Now we're able to @import CSS files into our main.css. So create a new file called src/headline.scss, move the headline styles from src/main.css to our new file and import it!

$ touch src/headline.scss
// src/headline.scss
h1 {
  color: #f6f7f8;

  &::after {
    content: ' 👋';
  }
}
// src/main.scss
// ...
// ...
// Remove old headline styles, instead import our new file
@import './headline.scss';
$ npm run css

> pcssdemo@1.0.0 css /Users/me/pcssdemo
> postcss src/main.scss -o assets/main.css --no-map --verbose

Processing src/main.scss...
Finished src/main.scss in 125 ms

Awesome! Our move from Sass to PostCSS seems to run smoothly. But of course, that's not everything you can do with PostCSS. Besides the ones we discovered in this post, there are plenty of other plugins that will do useful stuff.

Here are some of my favorites:

Take a look at postcss.parts to find more useful and sometimes funny plugins!