What it is
PostCSS is a newer term that has surfaced in the past year in web development, however the concept is not new. The idea got it’s start years ago with a node task runner plugin called autoprefixer, which you may already be using, if so you have been using postCSS. Plainly the definition of PostCSS is the act of transforming CSS with JavaScript plugins. PostCSS on it’s own is a tool that you get when you npm install postcss
. It provides an API to access CSS in the form of a parsed Abstract Syntax Tree (AST). This allows developers to create plugins to transform CSS and “compile” it’s output. There is even a boilerplate to help you get started writing your own plugin.
The name PostCSS sounds as if it applies only to post processing CSS, meaning applying transforms to a CSS file after compilation, but it is not limited to that. CSS preprocessors like SASS, LESS, Stylus, etc, that compile languages with features like variables, functions, mixins etc, to plain CSS can be used with PostCSS, or you can drop them altogether in favor of a pure JavaScript implementation of similar features that will more closely resemble the future of standard compliant CSS syntax, more on that in a bit.
Why you should use it
PostCSS plugins can do pretty much anything imaginable with CSS (preprocessing, sourcemaps, linting, etc) and that’s great but that isn’t the best reason to jump on board, the best reason is that it provides modularity to CSS development. Modularity can be the way that you build up your collection of postCSS plugins to transform your CSS (or SASS or LESS) exactly how you want it but it can also mean how you apply CSS in the browser.
Modularity is about breaking down a larger more complex system by solving problems and providing solutions to one problem at a time. This has been the latest fashion in JavaScript libraries like React but CSS isn’t really devised to be a modular system. Traditionally you would pick a framework, in the form of some language and preprocessor, and you are bound to it’s conventions and made to work inside it’s ecosystem. A lot of time you end up adding bloat to your project with code that you don’t even use, or worse yet you are overriding somewhere in a custom file. By letting go of the framework mentality and cherry picking only the plugins that you need to support your goals you can start focusing on solving your immediate needs and leaving the rest out. If you find that you have a specific use case, or one that you need to repeat on multiple applications, such as supporting older IE browsers, you can use a “pack” of plugins that are grouped together to provide that support, that is what the Oldie pack does.
CSS Modules
Another form of modularity that PostCSS provides, which takes writing CSS to a whole new level, is the ability to create CSS Modules. A module refers to a CSS file that is scoped to a local JavaScript module. This is done by using an intermediate file format called Interoperable CSS (ICSS) which compiles normally written CSS to locally scoped output.
Think about how you would add a module to an application, either by including a plugin or writing your own using JavaScript HTML and CSS. When you add this module to your application the JavaScript is added to the global scope of the application and the CSS is also added to the global browser context. JavaScript plugins avoid variable naming collisions and other negative effects of global scope by using self enclosed functions to wrap a module into it’s own execution context (more about scope) and providing a single namespaced variable to access it’s functionality. The same isn’t possible for CSS, everything is in global context and relies on specificity to retain tighter control on certain elements. To compensate for the nature of global CSS we have gotten used to crafting naming conventions, such as BEM, to define “namespaced” CSS that cascades with a rigid pedantic order. Unfortunately we have also gotten used to using some form of overrides to negate any top level styles that don’t work for a custom implementation. When we do this we are often adding more bloat, deeper specificity to the selector chain and causing our browser to do more work.
CSS Modules overcome this issue by defining everything in global scope with a unique selector that has been scoped to a DOM element generated with JavaScript. Class names are generated and compiled using PostCSS loaders with bundling tools that map and process the final CSS and JavaScript code with updated matching class names. This frees the developer from agonizing over naming conventions or worrying about performance hits.
Plugins
There are many useful plugins to use with postcss, but there are two that I feel are a must have, preCSS and cssnext (below). To explore other options there are resources like PostCSS.parts, a searchable catalog of plugins, and a section on HeyDesigner devoted to postcss articles, you should definitely check both of them out.
PreCSS
PreCSS is a tool that allows you to use Sass-like markup in your CSS files. You can see a full example fo all the things preCSS can do for you here. I have recently stopped using SASS all together in favor of pure CSS implementation using postcss plugins to process the output.
cssnext
cssnext (all lowercase) is a plugin similar to Babel for JavaScript, which transpiles future proposed ES6/7 syntax to ES2015 JavaScript, but for future CSS syntax such as custom media queries, calculated properties, pseudo syntax and more.
How to use it with Gulp
Now for the fun part, let’s start working with some code. For use with Grunt or Gulp we will be looking at a forked repository from Smashing Magazine they have written a great primer for those new to postcss with detailed examples of how to use plugins and future syntax.
How to use it with Webpack
For use with CSS modules a bundler like Webpack is required. Webpack is a bit more complex and it requires that you write your DOM in JavaScript to bundle the styles together with the CSS modules. We have a very simple demo setup on our SeattleFeministJS github to refer to. If you are experienced with React and would like to look at a more robust example you can find a great demo on the css-modules github which uses React.
Resources
- Tuts+ PostCSS Deep Dive: What you need to know
- css-tricks BEM 101
- Glen Maddern CSS Modules. Welcome to the Future
- Glenn Maddern Interoperable CSS. A CSS Standard for the Loader Age
- Jonathan T Neal PreCSS