PostCSS

PostCSS is a tool for transforming CSS with JS plugins. These plugins can add vendor prefixes, support variables and mixins, transpile CSS4 syntax, inline images, and more.
PostCSS can do the same work as "preprocessors" like Sass, Less, and Stylus. But PostCSS is modular, 4-40x faster, and much more powerful.
PostCSS is used by Google, Twitter, Alibaba, and Shopify. Its most popular plugin, Autoprefixer, is one of the most universally praised CSS processors available.
PostCSS itself is very small and focused. It includes a CSS parser, a CSS node tree API, a source map generator, and a node tree stringifier — and that's it. All of the stylesheet transformations it powers are encapsulated in modular plugins. And these plugins are themselves small and focused plain JS functions, which typically receive a CSS node tree at one end, apply transformations to it, and return a modified tree that can be used by other plugins or written to a file.
Individual plugins implement specific transformations; and by using various plugins together you can create an ideal CSS workflow for yourself and your team. For instance, if you like the power provided by preprocessors like Sass, you could combine Autoprefixer, cssnext, [CSS Grace], postcss-nested, postcss-mixins, and postcss-easings to write CSS like this:
@define-mixin social-icon $color {
& {
background: $color;
&:hover {
background: color($color whiteness(+10%))
}
}
}
.social-icon {
transition: background 200ms ease-in-sine;
font-variant-caps: small-caps;
&.is-twitter {
@mixin social-icon #55acee;
}
&.is-facebook {
@mixin social-icon #3b5998;
}
&:active {
opacity: 0.6;
}
}
@custom-media --mobile (width <= 640px);
@custom-selector --heading h1, h2, h3, h4, h5, h6;
.post-article --heading {
margin-top: 10rem;
@media (--mobile) {
margin-top: 0;
}
}
(Note that this is not the way to use PostCSS: this is just one possible feature set enabled by the plugins listed above.)
Twitter account for articles, releases, and new plugins: @postcss. Weibo account: postcss.
How PostCSS differs from Preprocessors (Sass, Less, etc.)
Preprocessors provide specialized languages that you can use to write CSS templates. These languages and their compilers are defined together in large codebases. Tools and libraries for preprocessors must work within each preprocessor's limitations: usually they can only offer sets of pre-defined mixins, functions, and variables.
In contrast, PostCSS provides a simple API that modular plugins can use to understand, transform, and create CSS. PostCSS plugins, therefore, can be created, maintained, and implemented independently. And they can perform many different tasks, not just compile special syntaxes to CSS. Each plugin does one thing well; and all PostCSS plugins do not have to fit together into a large "superset" language.
Features
Modularity
Without any plugins, PostCSS will parse your CSS and stringify it back to you without changing a single byte. All of the processing that enables special features and syntax in your stylesheets is made possible by PostCSS plugins, which are nothing more than JS functions.
Because each PostCSS plugin is an independent module, different plugins can take different approaches. This flexibility allows plugin authors to create whatever features they can imagine, while empowering PostCSS users to add only those features that they want to their workflow.
Some plugins, like postcss-custom-properties, postcss-media-minmax, and postcss-calc, implement syntax from present and future W3C specs, transpiling it to cross-browser-compatible output. Other plugins, like postcss-mixins and postcss-simple-extend, add new powers to your stylesheets that are not yet part of any spec. With PostCSS, you can decide for yourself which plugins match your own needs and preferences.
Variables provide a nice example of the flexibility that PostCSS offers. Right now, there are two different plugins that enable users to include variables in their stylesheets. postcss-simple-vars gives users a Sass-like syntax:
a {
color: $link-color;
}
postcss-custom-properties implements the syntax of the W3C CSS Custom Properties draft:
a {
color: var(--link-color);
}
Using PostCSS, you can choose which variables syntax you want to use — or even take both.
Another advantage of PostCSS's modularity is that anybody can contribute easily to the PostCSS ecosystem. Plugins are simple npm packages; so there are no barriers to writing your own plugins, or contributing ideas and bug fixes to the plugins that you use.
Perfomance
PostCSS is one of the fastest CSS parsers written in JS. (Only CSSOM is faster, and only because it is less accurate.) So PostCSS will read your CSS and apply transformations faster than any other stylesheet processor out there.
If you use Ruby Sass now, PostCSS could significantly improve your development process: PostCSS processing is 40 times faster than Ruby Sass compilation. And even if you throw in the entire cssnext plugin pack, PostCSS (written in JS) is still 4 times faster than libsass (written on C++).
Powerful Tools
PostCSS plugins can read and rebuild an entire CSS node tree. With this power, plugin authors are able to create tools that would be impossible to build into preprocessors (for example, Autoprefixer).
PostCSS-powered tools can do much more than transform special syntax into browser-friendly
CSS. PostCSS plugin authors have built linters (like doiuse and postcss-bem-linter),
code review tools (like list-selectors), and minifiers (like csswring).
With postcss-data-packer, you can create a cacheable "sprite"
by moving all data:uri values to separate file.
One unique example of PostCSS's power is RTLCSS. As you know, in some languages, such
as Arabic and Hebrew, writing moves from right-to-left (RTL), instead of the more widespread left-to-right
convention. Because a language's directionality affects its readers' perspective,
an international site's layout needs to change for RTL users, not just its text.
(Check out Arabic Wikipedia as an example.)
The RTLCSS plugin effectively "mirrors" your stylesheet by swapping left and right,
changing the value order in margin shorthands, and more.
Use the CSS of the Future
CSS3 added valuable features, but some of them are not yet available in all of the browsers that developers need to support. And exciting CSS4 modules are being drafted now — some even implemented in cutting-edge browsers — that will not be widely available for quite a while. But PostCSS plugins can allow us to write this CSS of the future, then transpile it to code usable in all the browsers we must support.
Autoprefixer exemplifies this power: you write spec-compliant, future-friendly CSS, pretending that vendor prefixes don't exist, and it does the dirty work of inserting the prefixes you'll need. All of the plugins bundled into cssnext do similar work, allowing authors to use syntax and functions from the latest W3C specs without worrying about the fallbacks they'll need.
As more CSS specs are drafted, more PostCSS plugins will be written. Users will be able to write stylesheets using standard, interoperable syntax, instead of a specialized language for a specialized tool (as with preprocessors).
Quick Start
- Implement PostCSS with your build tool of choice. See the PostCSS Grunt, Gulp, and webpack plugins more detailed instructions.
- Select plugins from the list below and add them to your PostCSS process.
- Make awesome products.
Plugins Packs
- cssnext contains plugins that allow you to use CSS4 features today.
- ACSS (Annotations-based CSS) contains plugins that transform your CSS according to special annotation comments.
Plugins
- Autoprefixer adds vendor prefixes for you, using data from Can I Use.
- cssgrace provides various helpers and transpiles CSS3 for IE and other old browsers.
- csswring is a CSS minifier.
- rtlcss mirrors styles for right-to-left locales.
- pixrem generates pixel fallbacks for
remunits. - css-mqpacker joins matching CSS media queries into a single statement.
- postcss-assets allows you to simplify URLs, insert image dimensions, and inline files.
- css2modernizr analyzes your CSS and creates a Modernizr config file that requires only the tests that your CSS will use.
- postcss-bem-linter lints CSS for conformance to SUIT CSS methodology.
- pleeease-filters converts WebKit filters to SVG filters, for cross-browser compatibility.
- postcss-custom-selectors adds custom aliases for selectors, using syntax from the W3C CSS Extensions draft.
- doiuse lints CSS for browser support, using data from Can I Use.
- webpcss adds URLs for WebP images, so they can be used by browsers that support WebP.
- postcss-import inlines the stylesheets referred to by
@importrules. - postcss-nested unwraps nested rules, as Sass does.
- postcss-media-minmax adds
<=and=>statements to media queries, using syntax from the Media Queries 4 draft. - postcss-mixins enables mixins more powerful than Sass's, defined within stylesheets or in JS.
- postcss-easings replaces easing names from easings.net with
cubic-bezier()functions. - postcss-url rebases or inlines
url()s. - postcss-epub adds the
-epub-prefix to relevant properties. - postcss-custom-properties supports variables, using syntax from the W3C CSS Custom Properties spec.
- mq4-hover-shim supports the
@media (hover)feature from the Media Queries 4 draft. - postcss-color-palette transforms CSS2 color keywords to a custom palette.
- postcss-custom-media supports custom aliases for media queries, using syntax from the Media Queries 4 draft.
- css-byebye removes the CSS rules that you don't want.
- postcss-simple-vars supports for Sass-style variables.
- postcss-data-packer moves embedded Base64 data out of the stylesheet and into a separate file.
- postcss-color-gray supports the
gray()function from the Color Module 4 draft. - postcss-brand-colors inserts company brand colors in the
brand-colorsmodule. - list-selectors lists and categorizes the selectors used in your CSS, for code review and analysis.
- postcss-calc reduces
calc()to values (when expressions involve the same units). - postcss-font-variant transpiles human-readable
font-variantproperties to more widely supported CSS. - postcss-simple-extend supports extending of silent classes,
like Sass's
@extendwith%placeholders. - postcss-size adds a
sizeshortcut that sets width and height with one declaration. - postcss-color-hex transforms
rgb()andrgba()to hex. - postcss-host makes the Shadow DOM's
:hostselector work properly with pseudo-classes. - postcss-color-rebeccapurple supports the
rebeccapurplecolor. - postcss-color-function supports functions to transform colors using W3C syntax.
- postcss-color-hex-alpha supports
#rrggbbaaand#rgbanotation from the Color Module 4 draft. - postcss-color-hwb transforms
hwb(), from the Color Module 4 draft, to widely compatiblergb(). - postcss-single-charset ensures that there is one and only one
@charsetrule at the top of your CSS.
Usage
JavaScript API
var postcss = require('postcss');
var processor = postcss([require('cssnext'), require('cssgrace')]);
var result = processor.process(css, { from: 'app.css', to: 'app.out.css' });
console.log(result.css);
Read the postcss function, processor, and Result API docs for more details.
Source Maps
Using source maps, a browser’s development tools can indicate the original position of your code in the source files, before any transformations were applied. For example, an inspector can show the position of a rule in a Sass source file, even if that file was compiled to CSS, concatenated, and minified.
To ensure that an accurate source map is produced, every CSS processing step should update the map that was generated by the previous step. For example, if a set of stylesheets are going to be compiled from Sass, concatenated, then minified, the concatenation tool should update the map generated during Sass compilation, and the minifier should update the map generated by the concatenation tool.
There are two ways to store and reference a source map:
-
External: The source map lives outside the CSS in a separate file. The CSS contains a special annotation comment pointing to the source map file.
a { } /*# sourceMappingURL=main.out.css.map */
* Inline: The source map is embedded in the CSS file as a Base64-encoded comment.
```css
a { }
/*# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFpbi5taW4uY3NzIiwic291cmNlcyI6WyJtYWluLmNzcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxJQUFLIn0= */
PostCSS has great source map support. It can read and interpret maps from previous transformation steps, autodetect the format that you expect, and output both external and inline maps.
To ensure that you generate an accurate
source map, you must indicate the input and output CSS files
paths — using the options from and to, respectively.
To generate a new source map with the default options, simply set map: true.
This will generate an inline source map that contains the source content.
If you don’t want the map inlined, you can use set map.inline: false.
var result = processor.process(css, {
from: 'main.css',
to: 'main.out.css'
map: { inline: false },
});
result.map //=> '{"version":3,"file":"main.out.css","sources":["main.css"],"names":[],"mappings":"AAAA,KAAI"}'
If PostCSS finds source maps from a previous transformation, it will automatically update that source map with the same options.
// main.sass.css has an annotation comment with a link to main.sass.css.map
var result = minifier.process(css, { from: 'main.sass.css', to: 'main.min.css' });
result.map //=> Source map from main.sass to main.min.css
If you want more control over source map generation, you can define the map
option as an object with the following parameters:
-
inline{boolean}: indicates that the source map should be embedded in the output CSS as a Base64-encoded comment. By default it istrue. But if all previous maps are external, not inline, PostCSS will not embed the map even if you do not set this option.If you have an inline source map, the
result.mapproperty will be empty, as the source map will be contained within the text ofresult.css. -
prev{string|object|boolean}: source map content from a previous processing step (for example, Sass compilation). PostCSS will try to read the previous source map automatically (based on comments within the source CSS), but you can use this option to identify it manually. If desired, you can omit the previous map withprev: false. -
sourcesContent{boolean}: indicates that PostCSS should set the origin content (for example, Sass source) of the source map. By default it istrue. But if all previous maps do not contain sources content, PostCSS will also leave it out even if you do not set this option. -
annotation{boolean|string}: indicates that PostCSS should add annotation comments to the CSS. By default, PostCSS will always add a comment with a path to the source map. But if the input CSS does not have any annotation comment, PostCSS will omit it, too, even if you do not set this option.By default, PostCSS presumes that you want to save the source map as
opts.to + '.map'and will use this path in the annotation comment. But you can set another path by providing a string value forannotation.If you have set
inline: true, annotation cannot be disabled.
Safe Mode
If you provide a safe: true option to the process or parse methods,
PostCSS will try to correct any syntax errors that it finds in the CSS.
postcss.parse('a {'); // will throw "Unclosed block"
postcss.parse('a {', { safe: true }); // will return CSS root for a {}
This is useful for legacy code filled with hacks. Another use-case is interactive tools with live input — for example, the Autoprefixer demo.