PostCSS, you beauty

Dimitrios Lytras
Monospace Pub
Published in
6 min readJul 5, 2017

--

These past few weeks I’ve been messing around with PostCSS. Everything about the said ecosystem is astounding and rightly so. Before we go any further, think of PostCSS as a preprocessor like your favorite one. Technically it’s not, but let’s take one step at a time.

First of all, what is it that makes the PostCSS’ approach much more attractive? Saving you some time, the answer is it’s modular approach, allowing the user to tweak the dependencies as he/she sees fit. PostCSS standalone does nothing. It’s up to you to include everything that benefits your development process. It’s essentially a tool, waiting to feed your awesome CSS to a number of Javascript plugins.

SASS and LESS are monolithic. You get everything, batteries included, and with that thousand of lines of code, you might not need. While it’s great to have a black box that just works, as a developer I prefer an ecosystem where I can use -among others- my own, tailor-made plugins. And this is the biggest sell of PostCSS. You can build ground up your CSS development process, exactly like you want.

Another distinct difference is that every pre-processor has its idiomatic syntax, limited to its own use. Essentially you write code inside CSS. Why not just write CSS separately and have Javascript do it’s ES6 magic afterward? Javascript isn’t going anywhere, can LESS say the same?

How it Works

Alright, let’s take the example of Autoprefixer, probably the most famous PostCSS plugin. Minding your own business, you decide to align these cat facts paragraphs, side by side. Something seems off, and you notice that they don’t have the same height. It’s expected, but it would be nice to arrange them in a way so border positions wouldn’t seem silly.

One dirty but effective approach is the following:

I shiver just by looking at it. But thanks to Flexbox we have a great tool in our hands to solve such problems. As expected though, for a Flexbox solution to work in all modern browsers, we have to use some prefixes

Now, what we should do is include the whole -Moz and -WebKit spam. While it might be alright for a small app, in more ambitious ones, we should search for alternatives.

In SASS you would create a mixin and have it include the prefixes needed. A simple include doesn’t seem much, but it’s still sub-optimal. What if in the following months, a prefix or two isn’t needed for the last X Chrome versions? Consider the box shadow case. Firefox & Chrome don’t need prefixes for shadows, but your SASS mixin would add them anyway.

The ideal case is to omit any prefix. Autoprefixer will parse the CSS code and will add itself only the necessary ones. The sole thing you have to do is to point out which browser versions you support. Consulting the caniuse database, Autoprefixer will take care of the rest.

How is that possible? Earlier I said that PostCSS does nothing without plugins. I lied. It certainly does one thing, which is to transform your CSS code to Abstract Syntax Tree (AST). A JSON-like data presentation, which every plugin will parse and modify. When everything is said and done, the output is stringified and ready for production.

You might wish to play around this example to get a better grasp of the whole AST transformation.

Notable Plugins

There are 200+ plugins out there, so it’s hard to list the ‘best’ ones. What I can do though, is to post the PostCSS configuration for a Gatsby website a made some days ago.

CSSnext allows me to use CSS specifications not quite supported yet by any browser. Variables, nesting and more will be available sooner or later. So why not use them today?

Font Magician is my favorite. When it came to decide which font to use for the said project, i wrote the following code:

Hot reloading allowed me to change the font-family without any effort and check six fonts under 30 seconds. That’s amazing. Due to the nature of the pet-project I worked on, I could get away with Google fonts. If you’d rather use self-hosted fonts, Font Magician can help you out in this case too.

Rucksack is a collection of very handy plugins. Its responsive font-size plugin is pure awesomeness. I used to do the following (credit to Keith j. Grant) to get responsive typography:

But with rucksack, I can just throw the following lines of code and be done with it

Of course, you can set some breakpoints for the upper and lower limits. I like it because you can have global responsive typography but can also target other elements in a nice manner.

I don’t like calc that much, and em units can be tricky from time to time. If for example, you want to have some specific rules about a call-to-action section, just do this and avoid pixels and breakpoints..

Lost is a nice to have plugin when you don’t want to use a CSS framework. I don’t use any in my side projects, so it saves some lines of code. Essentially you’re able to write concise code like the first three lines and have them expanded as follows. Pretty neat.

Finally postcss-autocorrect is a plugin I made.

There are moments when I make a typo, and I wonder why nothing changed. In this plugin, I correct these typos, the flow continues, and there is a warning in the console for the user. That’s all.

Making a plugin

Boilerplates are great, so clone this repo to quickstart the project.

Every bit of logic will be placed in index.js; there’s no magic here. We get the options if any, and parse the AST. Then it’s javascript business as usual.

For our showcase, let’s do something simple. Say we have the following code:

We will transform the @disable #efefef to:

Note that the & syntax is the way CSSnext works with nesting. Read more about the specification here. Ideally, you would include this plugin before CSSnext for the final output to make sense.

Alright, let’s get our hands dirty Follow each step here. Developing in this platform is much easier since you can check AST any time. Babel is also included; thus we can modify our code a bit like this:

In the above snippet, notice that we can parse every single CSS rule. Place a console.log and see for yourself. As for our example, we are only interested in declarations with an annotation. So let’s filter the rest out.

We’ve kept only the annotated declarations and the ones named ‘disable’. We expect to have only one in each selector. If that’s the case we’re free to delete the @disable #efefef entry and start building the output.

Creating a new rule, we pick the selector’s name and append the color declaration. To wrap things up, place the new rule inside the rule where the annotated declaration used to be.

Moving on, we remove the ES6 features that require Babel, to reduce our plugin’s dependencies, and we’re free to paste the code in index.js.

The output is correct and the crowd goes wild.

Well, that’s it. Just javascript. If you know what’s missing from your perfect CSS writing flow, you can create it! Before you do so thought, the PostCSS API docs are a must read. Keep it somewhere safe.

PostCSS opens infinite possibilities. Having the ability to hand-pick whatever plugin suits your needs, is clearly the best option.

I firmly believe that any developer willing to invest some time in this ecosystem will be highly rewarded. What’s better than making a plugin and using your own work as a dependency for another project?

Cheers!

--

--