Postcss is a transpiler of CSS. It is capable of analyzing and transforming CSS code just as Babel is capable of transforming CSS code. It also provides a plug-in mechanism to do custom transformations.
In this section, let’s get started with the postCSS plugin using a function that automatically converts PX to REM.
The principle of postcss
Postcss is a CSS-to-CSS translator. Like Babel, postCSS is divided into three stages: parse, Transform, and generate. All conversion plug-ins work in the transform phase, analyzing and transforming based on AST.
CSS AST is much simpler than JS. There are several main types:
Atrule: a rule that begins with @, as in:
@media screen and (min-width: 480px) {
body {
background-color: lightgreen; }}Copy the code
Rule: a rule at the beginning of a selector, such as:
ul li {
padding: 5px;
}
Copy the code
Decl: A specific style, such as:
padding: 5px;
Copy the code
Isn’t it much simpler than the dozens of AST’s from JS Parser?
These can be viewed visually through astExplorer.net
Postcss plug-in
The PostCSS plugin works in the Transform phase and handles ast nodes. The plugin looks like this:
const plugin = (options = {}) = > {
return {
postcssPlugin: 'Plug-in name',
Rule (node) {},
Declaration (node) {},
AtRule (node) {}
}
}
Copy the code
The outer function accepts options, returns an object of the plug-in, declares a listener for which node to process, and writes the processing logic in that listener.
You can also write:
module.exports = (opts = {}) = > {
return {
postcssPlugin: 'Plug-in name',
prepare (result) {
// We can put some common logic here
return {
Declaration (node) {},
Rule (node) {},
AtRule (node) {}
}
}
}
}
Copy the code
Prepare returns a variety of listeners, which has the advantage of storing some common logic over the first.
You can then run the plug-in like this:
const postcss = require('postcss');
postcss([plugin({
// options
})]).process('a { font-size: 20px; } ').then(result= > {
console.log(result.css);
})
Copy the code
Let’s write a simple PX auto rem plug-in to practice hand.
Practical cases
Requirements describe
Px is a fixed unit of length, and the size of the viewport of the device is various. If we want to adapt the display of various devices through a set of styles, we need a relative unit, and rem is commonly used.
The essence of REM is proportional scaling, relative to the font size of HTML elements.
For example, if the HTML font size is set to 100px, 1rem is equal to 100px, and if the style is 200px, 2rem is written.
In this way, we only need to change the FONT size of the HTML to fit the display of various screen widths, and the specific units will do proportional scaling.
We need to convert all px to REM according to the font size of the HTML. This is usually done manually, but it is a bit cumbersome. Once you know the calculation method, you can use the PostCSS plugin to do this automatically.
Let’s implement the PostCSS plugin
Code implementation
To build on the basic structure of the plug-in, we just need to declare a listener for Declaration processing:
const plugin = (options) = > {
return {
postcssPlugin: 'postcss-simple-px2rem',
Declaration (decl) {
}
}
}
Copy the code
Then all you need to do is convert the px in decl’s style value to REM, using a simple re substitution:
const plugin = (options) = > {
const pxReg = /(\d+)px/ig;
return {
postcssPlugin: 'postcss-simple-px2rem',
Declaration (decl) {
decl.value = decl.value.replace(pxReg, (matchStr, num) = > {
return num/options.base + 'rem'; }); }}}Copy the code
The replace method of the string is used. The first argument is the matching string, followed by the grouping. The first grouping is the value of PX.
To calculate the REM corresponding to PX, a PX value corresponding to 1REM is required, which can be passed in through options.
Then let’s test:
postcss([plugin({
base: 100
})]).process('a { font-size: 20px; } ').then(result= > {
console.log(result.css);
})
Copy the code
As you can see, the conversion has been done correctly:
Of course, our plugin is just a case in point, and it’s not perfect enough, but it would require more complex regex.
conclusion
Postcss is a TRANSPiler of CSS, just as Babel is a transpiler of JS, and the AST of PostCSS has only a few nodes, which are relatively simple and can be viewed visually through astExplorer.net.
Postcss also provides plug-in capabilities to do some custom analysis and transformation.
We have implemented a simple plug-in that automatically converts PX to REM:
Rem uses proportional scaling to achieve a set of styles for display of different device widths. It requires a TRANSFORMATION from PX to REM, which can be done automatically using the PostCSS plugin.
In fact, postCSS plugin analysis and conversion function has many applications, such as switching theme color, from white to black, you can use PostCSS automatically analyze the value of the color, and then do the conversion.
Postcss’s ability to analyze and transform CSS is still very powerful and useful, and there are many application scenarios in the business for you to explore.