PostCSS is a tool to transform CSS by JS plugins. This plugins can add vendor
prefixes, polyfill CSS 4 features, inline images, add variables
and mixins support. PostCSS with most popular Autoprefixer plugin
is used by Google, Twitter, Alibaba and Shopify.
PostCSS does same work as Sass, LESS or Stylus. But, instead of preprocessors,
PostCSS is modular, 4—40 times faster and much powerful
(Autoprefixer is impossible on preprocessors).
PostCSS is very small. It contains only CSS parser, CSS node tree API,
source map generator and node tree stringifier. All features (like variables
or nesting) are made by plugins. PostCSS plugin is just a JS function, that
accepts CSS node tree, reads and transforms some of nodes in tree.
For example, with Autoprefixer, cssnext, CSS Grace,
postcss-nested, postcss-mixins and postcss-easings plugins
you will be able to write this CSS:
@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;
}
}
Twitter account for articles, releases and new plugins: @postcss.
Weibo account: postcss.
Differences with preprocessors
- With preprocessors you write your CSS on special programming language.
It is like a PHP, but you mix control statement with styles. As result your
styles is slow, because programming language is too compilcated. With PostCSS
you write styles on normal CSS, just with custom at-rules and functions.
- Preprocessors tools (like Compass) is written mainly in same
preprocessors language. As result this tools is very limited. The libraries
adds only a custom functions, variables or mixins. There is no way to add new
syntax for CSS 4 polyfills. In PostCSS all magic is written on JS and uses
big universe of npm packages. So you have better and smarter tools.
- All features is built in this preprocessor’s language. Adding new features
is very difficult for developers, so languages develop slow. All features
of PostCSS is just a small JS functions, which transform CSS nodes tree.
Many developers create new features and you have bigger choice.
Features
Modularity
Without a plugins, PostCSS just parse your CSS and stringify it back without
change of any byte. All features is made by small JS funcions
from PostCSS plugins. You can choose only features, that you need.
Variables is a nice example. There are 2 different plugins for variables.
postcss-simple-vars has Sass like syntax:
a {
color: $link-color;
}
postcss-custom-properties is a polyfill for W3C CSS Custom Properties draft:
a {
color: var(--link-color);
}
In PostCSS you can choose what variables syntax you want or even take both.
Perfomance
PostCSS is one of the fastest CSS parsers written on JS. Only CSSOM is 10%
faster and only because it parses CSS not so accurate as PostCSS does.
Modular architecture makes PostCSS code is simple and easy to maintain.
As result PostCSS is incredible fast. PostCSS is written on JS, but even with
big cssnext plugin pack, it is 4 times faster than libsass written on C++.
If you uses Ruby Sass right now, you will be excited with PostCSS developing
process, because PostCSS is 40 times faster that Ruby Sass.
Powerful Tools
PostCSS plugins can read and rebuild entire CSS node tree.
As result PostCSS has many powerful tools that would be impossible
on preprocessors. Autoprefixer is a good example of how PostCSS plugin could
be useful.
PostCSS allows you to build linters (like doiuse or BEM Linter),
code review tools (like list-selectors) or minifiers (like CSSWring).
With postcss-data-packer plugin you can create a “sprite” from inlined images
by moving all data:uri
values to separated file.
But my favorite example of PostCSS power is RTLCSS. As you know Jews and Arabs
has right-to-left writing. Because writing affects to people perspective
you need to change your site design (check out Arabic Wikipedia).
RTLCSS plugin mirrors you design, replace left
to right
in your styles,
change values order in margin
, etc.
Quick Start
- Add PostCSS to your build tool. See Grunt, Gulp and webpack plugins
for further instructions.
- Select plugins from list below and add them to your PostCSS.
- Make awesome products.
Plugins Packs
- cssnext is a pack of CSS 4 polyfills plugins.
- ACSS contains plugins to control your CSS by special annotation comments.
Plugins
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 postcss function, processor and Result API docs for more details.
Source Maps
By using source maps, a browser’s development tools can indicate the
original position of your styles before the css file was transformed.
For example, an inspector will show the position in a Sass file, even if
the file has been compiled to CSS, concatenated, and minified.
To ensure a correct source map is generated, every CSS processing step should
update the map generated by the previous step. For example, a Sass compiler
will generate the first map, a concatenation tool should update the Sass step’s
map, and a minifier should update the map generated by the concatenation tool.
There are two ways to store a source map:
a { }
/*# sourceMappingURL=main.out.css.map */
* Or you can inline a base64-encoded source map within a CSS comment:
```css
a { }
/*# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFpbi5taW4uY3NzIiwic291cmNlcyI6WyJtYWluLmNzcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxJQUFLIn0= */
PostCSS has great source map support. To ensure that you generate the correct
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, provide map: true
.
This will inline sourcemap with source content. If you don’t want the map
inlined, you can use map.inline: false
option.
var result = processor.process(css, {
from: 'main.css',
to: 'main.out.css'
map: { inline: false },
});
result.map
If PostCSS is handling CSS and finds source maps from previous transformations,
it will automatically update the CSS with the same options.
var result = minifier.process(css, { from: 'main.sass.css', to: 'main.min.css' });
result.map
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 the source map should be inserted into the CSS
base64 string as a comment. By default it is true
. But if all previous map
are in separated too, PostCSS will not inline map too.
If you inline a source map, result.map
will be empty, as the source map
will be contained within the text of result.css
.
-
prev
(string, object, or boolean): map content from a previous processing
step (for example, Sass compilation). PostCSS will try to read the previous
source map automatically from the comment within origin CSS, but you can also
set manually. If desired, you can omit the previous map with prev: false
.
This is a source map option which can be passed to postcss.parse(css, opts)
.
Other options can be passed to the toResult(opts)
or process(css, opts)
methods.
-
sourcesContent
(boolean): indicates that we should set the origin content
(for example, Sass source) of the source map. By default it is true
.
But if all previous map do not contain sources content,
PostCSS will miss it too.
-
annotation
(boolean or string): indicates if we 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 previous CSS does not have an annotation
comment, PostCSS will omit it too.
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 as the annotation
option.
If you 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 error that it finds in the CSS.
postcss.parse('a {');
postcss.parse('a {', { safe: true });
This is useful for legacy code filled with plenty of hacks. Another use case
is interactive tools with live input, for example,
the Autoprefixer demo.
How to Develop PostCSS Plugin