PostCSS is a tool for transforming CSS with JS plugins. The growing ecosystem
of PostCSS plugins can add vendor prefixes, support variables and mixins,
transpile future CSS syntax, inline images, and more.
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 can do the same work as preprocessors like Sass, Less, and Stylus.
But PostCSS is modular, 4-40 times faster, and much more powerful.
Twitter account for articles, releases, and new plugins: @postcss.
Weibo account: postcss.
What is PostCSS
PostCSS itself is very small. It includes only a CSS parser,
a CSS node tree API, a source map generator, and a node tree stringifier.
All CSS transformations are encapsulated in modular plugins. And these plugins
are themselves small plain JS functions, which receive a CSS node tree,
apply transformations to it, and return a modified tree.
You can use the cssnext plugin pack and write future CSS code right now:
:root {
--row: 1rem;
--mainColor: #ffbbaaff;
}
@custom-media --mobile (width <= 640px);
@custom-selector --heading h1, h2, h3, h4, h5, h6;
.post-article --heading {
margin-top: calc(10 * var(--row));
color: color(var(--mainColor) blackness(+20%));
font-variant-caps: small-caps;
}
@media (--mobile) {
.post-article --heading {
margin-top: 0;
}
}
Or if you like the power provided by preprocessors like Sass,
you could combine postcss-nested
, postcss-mixins
, postcss-easings
and postcss-media-minmax
:
$mobile: width <= 640px;
@define-mixin social-icon $color {
background: $color;
&:hover {
background: color($color whiteness(+10%));
}
}
.social-icon {
transition: background 200ms ease-in-sine;
&.is-twitter {
@mixin social-icon #55acee;
}
&.is-facebook {
@mixin social-icon #3b5998;
}
}
.post-article {
padding: 10px 5px;
@media ($mobile) {
padding: 0;
}
}
How PostCSS Differs from Preprocessors
Sass, Less and Stylus 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.
Features
Modularity
Without any plugins, PostCSS will parse your CSS and convert it back
to the string 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.
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.
Performance
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 (like 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 CSS-sprite by moving all
data:uri
values to separate file.
One unique example of PostCSS’s power is rtlcss
. As you know,
in Arabic and Hebrew, writing moves from right-to-left, 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 Jews and Arabs, 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
CSS 3 added valuable features, but some of them are not yet available in all
of the browsers that developers need to support. And exciting future CSS 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 or CLI tool 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 future CSS features today.
- AtCSS contains plugins that transform your CSS according
to special annotation comments.
Future CSS Syntax
Fallbacks
Language Extensions
Optimizations
Shortcuts
Others
Analysis
postcss-bem-linter
lints CSS for conformance to SUIT CSS methodology.css2modernizr
creates a Modernizr config file
that requires only the tests that your CSS uses.doiuse
lints CSS for browser support, using data from Can I Use.list-selectors
lists and categorizes the selectors used in your CSS,
for code review.
Usage
JavaScript API
var postcss = require('postcss');
var processor = postcss([require('cssnext'), require('cssgrace')]);
processor
.process(css, { from: 'app.css', to: 'app.out.css' })
.then(function (result) {
fs.fileWriteSync('app.out.css', result.css);
if ( result.map ) {
fs.fileWriteSync('app.out.css.map', result.map);
}
});
Read the PostCSS API for more details.
Source Maps
PostCSS has great source maps 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: 'app.css',
to: 'app.out.css',
map: { inline: false },
});
result.map
If PostCSS finds source maps from a previous transformation,
it will automatically update that source map with the same options.
var result = minifier.process(css, { from: 'app.sass.css', to: 'app.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 that the source map should be embedded
in the output CSS as a Base64-encoded comment. By default it is true
.
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.map
property will be empty,
as the source map will be contained within the text of result.css
.
-
prev
string, object or 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
with prev: false
.
-
sourcesContent
boolean: indicates that PostCSS should set the origin
content (for example, Sass source) of the source map. By default it is true
.
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 or 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 for annotation
.
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 {');
postcss.parse('a {', { safe: true });
This is useful for legacy code filled with hacks. Another use-case
is interactive tools with live input — for example,
the Autoprefixer demo.
How to Develop PostCSS Plugin