TailwindCSS has a feature that:
You can remove unused CSS selectors for your project from compiled CSS files.
This functionality is implemented by PurgeCSS.
The link between TailwindCSS and PurgeCSS is a postCSS plugin @fullHuman/PostCSs-purgecss.
Not only TailwindCSS, but also many well-known projects use the postCSS plug-in. Such as:
Many people use the Autoprefixer plug-in in their projects to add different browser prefixes to CSS selectors.
Inside it, the browser version is specified based on Browserslist.
Go to Caniuse to find the browser version compatibility support.
Finally, the ability to overwrite unsupported CSS properties via postCSS.
As you can see, postCSS is increasingly becoming an essential dependency for front-end projects.
There are also many misconceptions about postCSS, such as that it is a CSS preprocessor like Less and Sass.
This article will cover postCSS from the bottom up and hopefully give you a better understanding of the killer.
What is a postCSS
PostCSS is a CSS compiler.
By analogy with @babel/ Parser of Babel family, JS code can be parsed into AST (abstract syntax tree), and the ability of many plug-ins (@babel/ plugin-XX) can be used to rewrite AST, and finally output the rewritten JS code.
PostCSS parses CSS code into AST using its parser, and then ADAPTS AST using a number of plug-ins (autoprefixer is one of them) to output the rewritten CSS code.
This is where it differs from CSS preprocessors like Less — postCSS’s inputs and outputs are CSS files.
For this reason, postCSS is also called a post-processor because it is usually at the end of the CSS processing chain.
The AST postCSS
You can choose from astExplorer:
-
Language: the CSS
-
Parser: postCSS
To see how postCSS parses CSS.
For example, for the following CSS code:
/** * I am KaSong */
@media screen and (min-width: 900px) {
article {
padding: 1rem 3rem; }}ul {
margin: 3rem;
}
ul li {
padding: 5px;
}
Copy the code
The AST is parsed by postCSS into the following tree structure:
Nodes are of the following types:
-
Root: indicates the Root node, representing a CSS file
-
AtRule: declarations beginning with @, such as @charset “utF-8” or @media (screen) {}
-
Rule: a selector that contains an internal definition, such as input, button {}
-
Declaration: key-value Specifies the key value pair, such as color: black.
-
Comment: indicates a separate Comment. Annotations for selectors, at-rule parameters, and value are in the Node attribute of the node
Implement a simple plug-in
Let’s see how developers can get involved in the postCSS compilation process from the implementation of a plug-in.
Postcss-focus adds :focus to all :hover selectors to improve the usability of keyboard operations.
For the following code:
.a:hover..b:hover..c:hover {
opacity:.5;
}
Copy the code
After processing by the plug-in, output:
.a:hover..b:hover..c:hover..a:focus..b:focus..c:focus {
opacity:.5;
}
Copy the code
You can install postCSS, postCSS-focus and see the result on the console with the following demo:
const postcssFocus = require('postcss-focus');
const postcss = require('postcss');
const fs = require('fs');
// Enter the CSS file address
const from = 'src/a.css';
const to = 'output/a.css';
fs.readFile(from.(err, css) = > {
postcss(postcssFocus).process(css, { from, to }).then(result= > {
console.log(result.css)
})
})
Copy the code
Postcss-focus source code implementation logic:
-
PostCSS parses the input CSS to an AST
-
Traverses all nodes of Rule type in the AST
-
Maintains an array that iterates over all of the node’s selectors, pushing a :focus selector into the array every time it iterates over a selector that contains :hover
-
Concat the array obtained in 2 into the existing selectors for this node
-
Output new CSS based on the changed AST
The core source code is as follows:
{
postcssPlugin: 'postcss-focus'./ / step 1
Rule: rule= > {
/ / step 2
if (rule.selector.includes(':hover')) {
let focuses = []
for (let selector of rule.selectors) {
if (selector.includes(':hover')) {
let replaced = selector.replace(/:hover/g.':focus')
if(! hasAlready(rule.parent, replaced)) { focuses.push(replaced) } } }/ / step 3
if (focuses.length) {
rule.selectors = rule.selectors.concat(focuses)
}
}
}
}
Copy the code
This plug-in is intended to demonstrate the basic workings of the plug-in, which is actually implemented rather crudely.
PostCSS provides detailed plug-in creation documentation. Create-postcss-plugin is even provided to create template code for plug-ins.
More possibilities
PostCSS plug-ins can be very versatile because they provide the ability to express and rewrite CSS AST. Such as:
postcss-functions
The Declaration node represents key-value pairs of CSS properties, where values are strings.
Then you can completely customize the value resolution rules.
body {
color: getColor(a); }Copy the code
By defining the getColor function and parsing it into function execution in the AST, you can write logic code in CSS files with JS.
This is postcss – functions provides
stylelint
Configure different Lint rules to implement static syntax detection of CSS. This is stylelint
conclusion
PostCSS plug-ins are classified as follows:
-
Solve global CSS issues, such as CSS Module support
-
Use CSS features that are not fully compatible, such as Autoprefixer
-
Formatting improves CSS readability
-
Image and word processing
-
Linters, such as stylelint
-
Different syntax CSS support, such as postCSS-html can parse THE CSS syntax inside the
At this point, you’ll agree that postCSS is the biggest killer of CSS processing than Less or Sass.