postcss插件的适配
在一个项目中,一个postcss的插件配置基本如下
module.exports = {
"plugins": {
"postcss-import": {},
"postcss-url": {},
"postcss-aspect-ratio-mini": {},
"postcss-write-svg": { utf8: false },
"postcss-cssnext": {},
"postcss-px-to-viewport": {
viewportWidth: 750,
viewportHeight: 1334,
unitPrecision: 3,
viewportUnit: 'vw',
selectorBlackList: ['.ignore', '.hairlines'],
minPixelValue: 1,
mediaQuery: false
},
"postcss-viewport-units":{},
"cssnano": {
preset: "advanced",
autoprefixer: false,
"postcss-zindex": false
}
}
}
接下来简单分析下各个配置文件的作用
postcss-import和postcss-url
postcss-import和postcss-url两个主要是用于处理引入的文件和资源路径的处理以及工作模式。
- postcss-import就是在一个css中用来@import css文件的
- postcss-url 是用于css的资源路径的 如果你的项目也使用的是Vue,并且配置了vue-loader,并且配置了相关的参数,那就就具有类似的功能。
autoprefixer
主要用来处理浏览器的私有前缀,这个已经是大家经常使用的一个PostCSS插件了。这里需要提出的是,如果你的项目中使用了postcss-next和cssnano,那么autoprefixer插件可以不引入,而且在postcss-next和cssnano两者中选择其一关闭autoprefixer,因为这两个插件都集成了autoprefixer插件的特性。
postcss-aspect-ratio-mini
主要用来处理元素容器宽高比。在项目当中很多地方会使用img、object或者video,那么这个插件能更好的帮助我们完美处理宽高比的缩放。在实际使用的时候,具有一个默认的结构:
<div aspectratio>
<div aspectratio-content></div>
</div>
在实际使用的时候,你可以把自定义属性aspectratio和aspectratio-content换成相应的类名,比如:
<div class="aspectratio">
<div class="aspectratio-content"></div>
</div>
我个人比较喜欢用自定义属性,它和类名所起的作用是同等的。结构定义之后,需要在你的样式文件中添加一个统一的宽度比默认属性:
[aspectratio] {
position: relative;
}
[aspectratio]::before {
content: '';
display: block;
width: 1px;
margin-left: -1px;
height: 0;
}
[aspectratio-content] {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
width: 100%;
height: 100%;
}
如果我们想要做一个188:246(188是容器宽度,246是容器高度)这样的比例容器,只需要这样使用:
[w-188-246] {
aspect-ratio: '188:246';
}
有一点需要特别注意:aspect-ratio属性不能和其他属性写在一起,否则编译出来的属性只会留下aspect-ratio的值,比如:
<div aspectratio w-188-246 class="color"></div>
编译前的CSS如下:
[w-188-246] {
width: 188px;
background-color: red;
aspect-ratio: '188:246';
}
编译之后:
[w-188-246]:before {
padding-top: 130.85106382978725%;
}
主要是因为在插件中做了相应的处理,不在每次调用aspect-ratio时,生成前面指定的默认样式代码,这样代码没那么冗余。所以在使用的时候,需要把width和background-color分开来写:
[w-188-246] {
width: 188px;
background-color: red;
}
[w-188-246] {
aspect-ratio: '188:246';
}
这个时候,编译出来的CSS就正常了:
[w-188-246] {
width: 25.067vw;
background-color: red;
}
[w-188-246]:before {
padding-top: 130.85106382978725%;
}
postcss-write-svg
主要用来处理移动端1px的解决方案。该插件主要使用的是border-image和background配合SVG绘制的矢量图来做1px的相关处理。
postcss-cssnext
其实就是cssnext。该插件可以让我们使用CSS未来的特性,其会对这些特性做相关的兼容性处理。著作权归作者所有。
cssnano
主要用来压缩和清理CSS代码。在Webpack中,cssnano和css-loader捆绑在一起,所以不需要自己加载它。不过你也可以使用postcss-loader显式的使用cssnano。
- 删除空格和最后一个分号
- 删除注释
- 优化字体权重
- 丢弃重复的样式规则
- 优化calc()
- 压缩选择器
- 减少手写属性
- 合并规则
postcss-px-to-viewport
两个PostCSS插件主要是用于vw适配方案,算是这次项目中必不可少的PostCSS插件。其中,postcss-px-to-viewport插件主要用来把px单位转换为vw、vh、vmin或者vmax这样的视窗单位,也是vw适配方案的核心插件之一。
在配置中需要配置相关的几个关键参数:
"postcss-px-to-viewport":
{
viewportWidth: 750, // 视窗的宽度,对应的是我们设计稿的宽度,一般是750
viewportHeight: 1334, // 视窗的高度,根据750设备的宽度来指定,一般指定1334,也可以不配置
unitPrecision: 3, // 指定`px`转换为视窗单位值的小数位数(很多时候无法整除)
viewportUnit: 'vw', // 指定需要转换成的视窗单位,建议使用vw
selectorBlackList: ['.ignore', '.hairlines'], // 指定不转换为视窗单位的类,可以自定义,可以无限添加,建议定义一至两个通用的类名
minPixelValue: 1, // 小于或等于`1px`不转换为视窗单位,你也可以设置为你想要的值
mediaQuery: false // 允许在媒体查询中转换`px`
}
postcss-viewport-units
由于浏览器对vw还具有一定的兼容性,其在Android 4.4之下和iOS8以下的版本都存有一定的问题。为了让vw、vh、vmin和vmax这些viewport单位能更好的使用。其兼容方案就是使用viewport的polyfill:Viewport Units Buggyfill。
而在采用Viewport Units Buggyfill的时候,需要手动给使用viewport单位的样式中添加其对应的Hack代码,比如:
.box {
top: 2vw;
left: 1vw;
content: 'viewport-units-buggyfill;top: 2vw;left: 1vw;';
}
如果每一个都这样来做,那么将是灾难性的。幸运的是,可以使用postcss-viewport-units。其主要是给CSS的属性添加content的属性,配合viewport-units-buggyfill库给vw、vh、vmin和vmax做适配的操作。
另一个坑,使用postcss-viewport-units将会给具有content属性的元素造成一定的影响,比如你的项目中使用伪元素::before、::after或者伪类:before、:after之类。那么使用该插件,会自动替换你原来的content内容,为了避免该现象,需要在content的属性值末尾添加!important。