First steps with PostCSS

PostCSS is getting a lot of attention lately and I decided to give it a try. Post-processing may seem counter intuitive especially if you are used to tools like SASS and LESS, but will make more sense the more time you spend tinkering.

With a post-processor you can define global styles that can then be transformed into specific rules for different components of the web application. This is really quite powerful and allows for creating of a simple set of styles that can then be targeted at specific components.  One use would be to have a branding stylesheet that can be applied to different plugins or products.

The concept is somewhat similar to what you can do using pre-processors (eg. Bootstrap and variables) but way more flexible and arguably much cleaner as well.  As the base stylesheet could remain unchanged and processing code is added with each additional integration.

Of course, that is only one way to utilize the functionality but the possibilities are countless.
There is a lot of potential here and for workflows that are clean and reusable so make sure to give PostCSS a try. Here are some steps to get up and running quickly:

  1. Install node.js (if you haven’t already)
  2. Create a folder for the test project.
  3. Access command line and go into the folder.
  4. Run the following commands to install the CLI version of the PostCSS package as well as the Autoprefixer plugin. (There are several other PostCSS plugins available and you also have the ability to create your own – the main strength of PostCSS).

The CLI version is a wrapper around the regular PostCSS package and allows you to run PostCSS without any additional build packages. Good for getting to know how it works.

npm install postcss-cli
npm install autoprefixer

The commands will install the packages under node_modules directory created in your current directory.

  1. Create a test file called test.css with the following content.
.transparent {
  opacity: 0;
  transition: opacity 1s;
}
  1. Create an options file called test.json with PostCSS and Autoprefixer options. This allows you to configure parameters for the autoprefixer plugin. In this case a query for supported browsers (see: https://github.com/ai/browserslist#queries)
{
  "use": ["autoprefixer"],
  "autoprefixer": {
    "browsers": "> 5%"
  }
}
  1. Execute the following command to compile the css. result.css will contain the output.
postcss -c test.json -o result.css test.css

You should see that the autoprefixer plugin added browser specific prefixes.

Styling nested elements with LESS

LESS is a great tool for removing the tediousness out of CSS styling by allowing nested selectors and use of variables.
But there is much more to the language allowing for more complex logic to be embedded. One of the great features of the language is the ability to loop and create styles recursively.

A good practical use for this functionality is to style a comments section:

See the Pen Styling nested elements with LESS by Marcin Jackowiak (@marcinjackowiak) on CodePen.

Below is the basic LESS code will generate CSS that varies the div background color depending on how deep the element is in the DOM hierarchy.
It is a prime example of something that could be a nightmare to maintain directly in the CSS stylesheet.

#namespace {
  .test(@i,@x) {
    div {
      background-color: lighten(red, @i*(50/@x));
    }
  }

  .recursive(@x; @i:0) when (@i <= @x) {
      .test(@i,@x);
      div {
        .recursive(@x; (@i+1));
      }
  }
}

div {
  width: 200px;
  height: 200px;
  padding: 20px;
  border: 1px solid #888;
}

& { #namespace > .recursive(5); }

What it generates is a nice gradient of red that will lighten the deeper you go.
The following formula will lighten the color by 50% with each level. To create a smoother transition simply lower the
number.

      background-color: lighten(red, @i*(50/@x));

The argument in the .recursive mixin allows you to specify the depth to which the styles will be generated.

& { #namespace > .recursive(5); }

The resulting CSS is as follows.

div {
  width: 200px;
  height: 200px;
  padding: 20px;
  border: 1px solid #888;
}
div {
  background-color: #ff0000;
}
div div {
  background-color: #ff3333;
}
div div div {
  background-color: #ff6666;
}
div div div div {
  background-color: #ff9999;
}
div div div div div {
  background-color: #ffcccc;
}
div div div div div div {
  background-color: #ffffff;
}