本章主要介绍,目前常用的一些第三方插件。
较为完整的插件列表可以参考PostCSS Plugins。
autoprefixer
autoprefixer 可以为 CSS
属性自动添加 prefix
前缀。
譬如 CSS3
中的 flex
布局、或者 transform
转换等。
该插件由于跟目标浏览器的版本相关,因此需要在项目根目录下配置 .browserslistrc
、或者在 package.json
文件下添加 browserslist
字段。
譬如:
> 1%
last 2 versions
not ie <= 8
# not dead => IE 10 has been dead
{
"browserslist": [
"> 1%",
"last 2 versions",
"not ie <= 8"
]
}
如果使用该插件的过程中, CSS
没有出现对应前缀,那么可以使用 npx autoprefixer --info
来 debugger
。
也可以利用 JS
的形式,console.log(autoprefixer().info())
。
postcss-import
postcss-import 在 CSS
文件中,可以使用 @import url()
语法。
譬如:
/* entry.css */
@import url(./flex.css);
@import url(./transform.css);
/* flex.css */
.flex {
display: flex;
}
/* transform.css */
.container {
transform: scale(2);
user-select: none;
}
添加 postcss-import
插件后,@import url()
语句便能够正常解析,从而将 flex.css
与 transform.css
中的内容整合到 entry.css
中。
postcss-url
postcss-url 可以用来处理 CSS
中的图片。
譬如,将 CSS
中的图片转换为 base64
形式:
.avatar {
width: 80px;
height: 80px;
background-image: url('../img/avatar.jpeg');
background-size: 100% 100%;
}
// .postcssrc.js
const autoprefixer = require('autoprefixer')
const postcssImport = require('postcss-import')
const postcssUrl = require('postcss-url')
module.exports = ctx => {
return {
plugins: [
autoprefixer({}),
postcssImport({}),
postcssUrl({
url: 'inline'
})
]
}
}
postcss-pxtorem
postcss-pxtorem 可以用来将项目中的 px
单位自动转换为 rem
。
默认转换比例为 1 : 16
,即 1rem = 16px
。
在实际项目中,通常会与 lib-flexible 结合使用:
const autoprefixer = require('autoprefixer')
const postcssImport = require('postcss-import')
const postcssUrl = require('postcss-url')
const postcssPxToRem = require('postcss-pxtorem')
module.exports = ctx => {
return {
plugins: [
autoprefixer({}),
postcssImport({}),
postcssUrl({}),
postcssPxToRem({
// 默认 16,即1rem = 16px。如果结合lib-flexible的话,以375设计稿为例。lib-flexible会将html的font-size设置为375 / 10 即37.5,则此处应对应修改。
rootValue: 40,
// 设定最小px值 当目标值小于该值时,不进行rem转换。通常,不转换字体图标。
minPixelValue: 2,
// 指定哪些属性进行rem转换,如font-size、width等,设置为*,代表所有属性均可进行转换。
propList: ['*'],
// 选择器黑名单 当目标元素使用了黑名单选择器,则该选择器下的属性,不进行rem转换。
selectorBlackList: []
})
]
}
}
postcss-px-to-viewport
postcss-px-to-viewport 可以用来将 px
单位自动转换为 vw
。
该方式是lib-flexible@2.0靠近且推荐的实现。
但是在 2023
年的笔者看来,在实际项目中使用 postcss-px-to-viewport
,依然有待商榷。
相比之下,笔者依然推荐lib-flexible@1.0结合postcss-pxtorem,操作很方便且简单易行,最重要的是设置了最大参考宽度为 540px,在大屏上不会过大。
以下简单记录下 postcss-px-to-viewport
的引入方式和使用方法:
const autoprefixer = require('autoprefixer')
const postcssImport = require('postcss-import')
const postcssUrl = require('postcss-url')
const postcssPxToViewport = require('postcss-px-to-viewport')
module.exports = ctx => {
return {
plugins: [
autoprefixer({}),
postcssImport({}),
postcssUrl({}),
postcssPxToViewport({
unitToConvert: "px", // 要转化的单位
viewportWidth: 750, // UI设计稿的宽度
unitPrecision: 6, // 转换后的精度,即小数点位数
propList: ["*"], // 指定转换的css属性的单位,*代表全部css属性的单位都进行转换
viewportUnit: "vw", // 指定需要转换成的视窗单位,默认vw
fontViewportUnit: "vw", // 指定字体需要转换成的视窗单位,默认vw
selectorBlackList: ["wrap"], // 指定不转换为视窗单位的类名,
minPixelValue: 1, // 默认值1,小于或等于1px则不进行转换
mediaQuery: true, // 是否在媒体查询的css代码中也进行转换,默认false
replace: true, // 是否转换后直接更换属性值
exclude: [/node_modules/], // 设置忽略文件,用正则做目录名匹配
landscape: false // 是否处理横屏情况
})
]
}
}
postcss-nesting
postcss-nesting是基于[CSS官网嵌套规范]而制定的插件。
.foo {
color: red;
&:hover {
color: green;
}
> .bar {
color: blue;
}
@media (prefers-color-scheme: dark) {
color: cyan;
}
color: pink;
}
/* becomes */
.foo {
color: red;
color: pink;
}
.foo:hover {
color: green;
}
.foo > .bar {
color: blue;
}
@media (prefers-color-scheme: dark) {
.foo {
color: cyan;
}
}
postcss-nested
postcss-nested则是基于[Sass]嵌套规范而制定的插件。
.phone {
&_title {
width: 500px;
@media (max-width: 500px) {
width: auto;
}
body.is_dark & {
color: white;
}
}
img {
display: block;
}
}
.title {
font-size: var(--font);
@at-root html {
--font: 16px
}
}
/* Becomes */
.phone_title {
width: 500px;
}
@media (max-width: 500px) {
.phone_title {
width: auto;
}
}
body.is_dark .phone_title {
color: white;
}
.phone img {
display: block;
}
.title {
font-size: var(--font);
}
html {
--font: 16px
}
postcss-preset-env
postcss-preset-env 是基于 browserslist
的样式预设。
所有的属性支持可以在CSSDB中查看。
如果目标浏览器不支持某 CSS
属性,则 postcss-preset-env
会尝试提供 JavaScript
版本的 polyfill
以实现 CSS
设置。
另外,要注意的一点是,postcss-preset-env
内置了 autoprefixer
功能。
譬如有如下配置:
// const autoprefixer = require('autoprefixer')
const postcssImport = require('postcss-import')
const postcssUrl = require('postcss-url')
const postcssPresetEnv = require('postcss-preset-env')
module.exports = ctx => {
return {
plugins: [
// autoprefixer({}),
postcssImport({}),
postcssUrl({
url: 'inline'
}),
postcssPresetEnv()
]
}
}
.browserslistrc
文件内容如下:
> 1%
last 2 versions
# not dead => IE 10 has been dead
not ie <= 8
则以下 entry.css
:
/* entry.css */
@custom-media --viewport-medium (width <= 50rem);
@custom-selector :--heading h1, h2, h3, h4, h5, h6;
:root {
--mainColor: bisque;
}
html, body {
width: 100%;
height: 100%;
background-color: var(--mainColor);
font-family: system-ui;
overflow-wrap: break-word;
}
:--heading {
@media (--viewport-medium) {
margin-block: 0;
}
}
a {
color: rgb(0 0 100% / 90%);
&:hover {
color: rebeccapurple;
}
}
会被转换成如下 output.css
:
@custom-selector :--heading h1, h2, h3, h4, h5, h6;
:root {
--mainColor: bisque;
}
html, body {
width: 100%;
height: 100%;
background-color: bisque;
background-color: var(--mainColor);
font-family: system-ui, -apple-system, Segoe UI, Roboto, Ubuntu, Cantarell, Noto Sans, sans-serif;
word-wrap: break-word;
}
:--heading {
@media (max-width: 50rem) {
margin-top: 0;
margin-bottom: 0;
}
}
a {
color: rgba(0, 0, 255, 0.9);
&:hover {
color: #639;
}
}