PostCSS常用插件简介继上一期PostCSS学习指南(一)后,逐渐开始在项目中应用。这次决定主要讲解一些个人认为非常有帮助的PostCSS插件。本期主要介绍以下插件和坑autoprefixerpostcss-partial-importpostcss-advanced-variablescssnanopostcss-px2remprecsspostcss-nesting和postcss-nested的坑(???)?autoprefixer不用多说,这是必装插件之一。编写标准的css很方便,它将为您提供一个非常完整的hack兼容解决方案。当然,这里需要了解的是它兼容的大部分数据源CanIUse。另一个需要了解的插件配置参数是浏览器。比如这样写:module.exports={plugins:[require('autoprefixer')({browsers:'last2versions'})]}这个参数的详细介绍可以在BrowserslistQueries中找到。文章中提到,强烈建议将query写到package.json中(稍后会告诉你为什么要写在这里),以及postcss.config.js中autoprefixer的非配置浏览器参数。因此,这里建议的写法如下:postcss.config.jsmodule.exports={plugins:[require('autoprefixer');]}在package.json中添加如下例子"browserslist":[">1%","last2versions"]这里简单说下数组中的值对官方文档的意义:last2版本:每个浏览器中的最新两个版本。>5%或>=5%:全球浏览器使用率大于或等于5%(上例中为1%)。其他一些参数简单介绍一下:ie6-8:选择包含ie6-8的版本。Firefox>20:Firefox版本号大于20,还有很多就不一一列举了。这里的配置还是很详细的。一般来说,最方便的方式是不加参数,按照默认即可。如果需要配置,在package.json中添加browserslist参数,其他插件也可以从中获取项目的兼容版本。目前,以下插件会读取和修改配置:Autoprefixerbabel-preset-env(noconfigsupport,onlytooloption)eslint-plugin-compatstylelint-no-unsupported-browser-featurespostcss-normalize这几乎是autoprefixer的介绍~postcss-partial-import没啥好说的,也是一个通俗易懂的插件,让你的css文件支持@import,支持W3C的写法,也支持SASS的写法,就不说了这里多说。postcss-advanced-variables也是一样,和SASS一样,可以自定义变量并引用,用法也很简单。相信不用点开官方文档你也能用上。胡凯链接综合症,恐怕漏掉了什么。)cssnano显然这个插件的作者是比较高调的。github的cssnano上没有解释和介绍,当然官方写的很详细。这个插件给我的感觉就是一个css代码压缩工具(其实集成了很多增强的功能,表面上看压缩其实做了很多处理,可以看这个表格Optimisations),而他的配置建议使用默认配置,除非你知道自己在做什么。当然我在测试中遇到了一点小问题,关于cssnano和autoprefixer的结合使用,还是因为导入postcss.config.js插件的顺序导致输出不同的问题?目前还在研究中,先看代码:testcssnano.css.test{-moz-border-radius:10px;边界半径:10px;display:flex;}postcss.config.js(firsttype)module.exports={plugins:[require('cssnano')({preset:'default',}),require('autoprefixer')]}输出结果:.test{border-radius:10px;display:flex}postcss.config.js(第二种)module.exports={plugins:[require('autoprefixer'),require('cssnano')({preset:'default',})]}输出结果:.test{border-radius:10px;display:-webkit-box;display:-ms-flexbox;display:flex}问题1,如果你手写-moz-,cssnano会清空,看例子,当然可能火狐已经支持这个属性没有前缀,所以它会被删除。问题2,如果在配置文件中,cssnano在autoprefixer之前被引用,假设webpack的loader执行顺序规则是一样的,很可能postcss.config.js中的插件也是从下往上依次执行的。因此,在第一个例子中,css代码先经过autoprefixer处理,然后再执行cssnano清除那些多余的前缀代码?大致可以分解为:第一步autoprefixer处理结果:.test{-moz-border-radius:10px;边界半径:10px;显示:弹性;显示:-webkit-box;display:-ms-flexbox;}两步cssnano处理的结果:.test{border-radius:10px;display:flex}但是很遗憾的告诉你。..这可能是一个错误的结论!!!因为我使用第一步的结果作为初始css,所以在postcss.config.js中只执行一个cssnano插件的结果如下:.test{border-radius:10px;display:flex;display:-网络工具箱;display:-ms-flexbox}所以,这个问题就来了。..cssnano确实删除了-moz-,但他不处理其他有关显示的兼容代码。所以我做了另一个测试:我将css代码更改为:.test{-webkit-transform:scale(.5)translate(10,20);-moz-transform:scale(.5)translate(10,20);-ms-transform:scale(.5)translate(10,20);-o-transform:scale(.5)translate(10,20);转换:比例(.5)翻译(10、20);}而postcss.config.js还是同时引入了cssn??ano和autoprefixer。经过测试,无论谁先,输出结果都是:.test{-webkit-transform:scale(.5)translate(10,20);transform:scale(.5)translate(10,20)}如果css代码改为:.test{transform:scale(.5)translate(10,20);}postcss.config.js同时引入了cssn??ano和autoprefixer,第一个cssnano之前的结果:.test{transform:scale(.5)translate(10,20)}第二个autoprefixer之前的结果:.test{-webkit-transform:scale(.5)translate(10,20);transform:scale(.5)translate(10,20)}的结果又不一样了,不知道大家看到这里是不是晕了。根据观察,postcss.config.js插件的执行顺序是有要求的。至少同时使用cssnano和autoprefixer时,cssnano必须在autoprefixer之后,否则autoprefixer可能会失败!另外cssnano和autoprefixer都会简化很老的兼容写法。比如上面有一段CSS代码,有很多transform属性,autoprefixer会(根据browserslist)剔除其他的。至于顺序问题,后面会继续研究!postcss-px2rem作为移动端使用,适配很头疼。不过我还是用的稳定方案flexible,所以需要用rem作为主体。这里不说适配问题,只说这个插件,一般是移动端,设计师给的设计稿是750px宽,只需要设置如下,直接就可以在代码中用PSD写下你的像素值,真是太刺激了!require('postcss-px2rem')({remUnit:75,threeVersion:true})因为这个postcss-px2rem是从px2rem派生出来的,所以详细说明见px2rem。我这里写了两个参数,一个是remUnit,这个是对应每一个rem对应的px值。既然是750px,就写75吧,不知道这个理解对不对。另外三个Version分别对应三个不同dprs下的size。这个比较少用。需要注意的是如何处理这些参数。是否转换rem与注释有关。这里就不细说了,看文档就知道了~当然这里也是埋了一个坑,后面会提到。Precss是一个大杂烩,主要是为了满足SASS开发者的习惯,继承了很多插件。本文前后提到了precss中的一些插件。如果不是全部用到,我建议一个一个手动安装。配置需要插件。这个东西配置好后不会经常改,个人觉得大杂烩容易出一些坑,很难排错。比如下面这两款插件,大家仔细看看。还有几个插件,推荐安装(当然,如果你不知道该怎么做,你可以忽略它们):嵌套的CSS在根。有一个官方的bar.css的@import例子很棒。你可以看看它。Postcss-extend具有相同的结构,但有一点不同。这样可以方便的管理相同部分的样式代码。其他的我个人觉得不常用或者据说实际意义不大,所以没有写出来。postcss-nesting和postcss-nested也取自precss,是模仿SASS的嵌套css写法。为什么把这两个写在一起,因为它们看起来很像。光看名字,鬼都知道区别,不过都加到precss里了。根据precss,这两者的区别是:postcss-nesting:W3Cnestedselectorspostcss-nested:Sass-likenestedselectors光看这两行,看不懂是什么东西。第一个是符合W3C规范的吗?嵌套选择?粗略看了下两个插件的文档,没看出有什么区别。OK,那就手动写代码一一尝试吧。先安装postcss-nesting,试编译,是红色的。..这是怎么回事,我们先看代码片断。.catis-list{填充:050px;溢出:隐藏;li{列表样式:无;向左飘浮;边距顶部:38px;宽度:113px;&:not(:nth-child(4n)){margin-right:66px;}.iconfont{字体大小:100px;行高:100px;颜色:#506071;显示:块;文本对齐:居中;}.cati-name{字体大小:28px;高度:40px;显示:块;颜色:#999;文本对齐:居中;}}}SASS的写法好像没有问题。但是它提示的错误信息让人无法理解ERRORin./src/style/index.cssModulebuildfailed:ModuleBuildError:Modulebuildfailed:Error:undefined:783:6:propertymissing':'aterror(D:\webProjects\mobileweb\node_modules\css\lib\parse\index.js:62:15)在声明处(D:\webProjects\mobileweb\node_modules\css\lib\parse\index.js:223:33)在声明处(D:\webProjects\mobileweb\node_modules\css\lib\parse\index.js:252:19)少了一个冒号。..来回改是不对的。直接用官方的例子。只有这样我才能看清楚。原来每一个嵌套的样式前面都需要一个&(注意符号后面有一个空格)。其实应该是这样的:.catis-list{padding:050px;溢出:隐藏;&li{列表样式:无;向左飘浮;边距顶部:38px;宽度:113px;&:not(:nth-child(4n)){margin-right:66px;}&.iconfont{字体大小:100px;行高:100px;颜色:#506071;显示:块;文本对齐:居中;}&.cati-name{字体大小:28px;行高:40px;显示:块;颜色:#999;文本对齐:居中;}}}有一个部分使用了&符号后没有空格的伪类,这是正确的。编译结果:.catis-list{padding:00.666667rem;溢出:隐藏;}.catis-listli{列表样式:无;向左飘浮;保证金顶部:0.506667rem;宽度:1.506667rem;}.catis-listli:not(:nth-child(4n)){margin-right:0.88rem;}.catis-listli.iconfont{font-size:1.333333rem;行高:1.333333rem;颜色:#506071;显示:块;text-align:center;}.catis-listli.cati-name{字体大小:0.373333rem;行高:0.533333rem;显示:块;颜色:#999;center;}那么就没有问题了。和官方描述的一样,但是另一方面,如果每次都要写&加空格,那岂不是很麻烦,写惯了SASS的兄弟肯定不愿意这样做。所以我想说的是另一个插件postcss-nested,正如precss所说,这确实是SASS-LIKE。当然我还是不太明白为什么precss需要包含两个嵌套插件(为了满足不同开发者的习惯?)。我们修改postcss.config.js使用postcss-nested,重新修改样式代码前的第一段,再次编译执行,一切OK,那么结论就是,如果你只习惯了嵌套的写法SASS,可以安装postcss-nested插件~坑(???)?最后说一下我遇到的坑,除了前面提到的cssnano和autoprefixer,需要注意顺序。还有一个顺序研究,就是在确定了要使用的插件之后,在postcss.config.js中配置插件requireorder还是很重要的。我个人的观察这里确实是从上到下(至于是不是每一个我都不确定依次处理完文件之后再去执行),比如postcss-partial-import应该是最先引入的,如果放在最后,css代码第一行使用@import肯定会报错!所以建议根据css代码的写法来决定你的执行顺序。postcss-nested插件是大多数SASS开发者的最爱,但是在使用sass编写css文件时会遇到以下问题:csslint,css文件不支持嵌套,变量等,如果将文件模式改为Forsass,评论方式会变成//而不是/*评论*/,当然你可以手写/*...*/这样的评论,但是用快捷键评论会很痛苦。这里有一个小技巧可以让项目的所有css文件都以sass方式编辑,在项目的settings.json中添加:"files.associations":{"*.css":"scss"}当然如果你想要支持//评论也可以,请安装postcss-scss插件,这个我这里就不多说了,因为我已经决定要手写评论了?你手写的注释没有问题,但是编译出来的东西就会有问题。如果你style的最后一行在花括号里面写注释,它转换的代码,注释就会在外面,这是一个大坑,因为在使用postcss-px2rem的时候,注释控制是否转换的作用是无效的。我的文字描述可能比较乱,看代码:比如CSS部分的代码:.test{color:#999;边框:1px实心#ddd;/*没有*/.inner{color:#333;}}转换后:.test{color:#999;border:0.13333remsolid#ddd;}/*no*/.test.inner{color:#333;}而不是我想要的:.test{color:#999;border:1pxsolid#ddd;}.test.inner{color:#333;}理论上应该输出我想要的结果,但是输出不正确。原因是postcss先执行After-nested把注释放在外面,postcss-px2rem无法识别其规则。我一开始安装precss后也发现了这个问题,后来找了半天才发现是这个插件的问题。同时我也发现这个人其实也提到了Wronglocationofcommentofthelastdeclarationinanestedruledefinition这个问题,但是没有人解决。而我暂时的处理方式是最后一行不写要注释的代码。如下:.test{border:1pxsolid#ddd;/*没有*/color:#999;.inner{颜色:#333;}}有时候底部的border可能没有两种样式,如果只有一行border,只能这样:.test{.inner{color:#333;}border:1pxsolid#ddd;/*no*/}这样可以,但是看起来很奇怪,所以如果你用同一个方法处理的时候,一定要注意这一点(我写完这个好像找到了更好的解决方法文章。确定没有问题后,我会写在下一期~)。(我记得好像有个坑,想了半天想不起来了。。。所以我们先做这个)在本期的最后,如果你想探索更多好玩好用的插件,可以看看PostCSS插件列表和这个可搜索的分类插件列表,如果你发现更好的插件,欢迎离开留言~另外,如果上面的例子不是很清楚,或者只是想直接拿来快速测试一下,可以看看这个mobileweb(PostCSS第三期的内容还在考虑中...可能是对第二期的补充和填坑~敬请期待?)关于我个人的PostCSS其他系列的学习、介绍和总结,感兴趣的可以参考:PostCSS自学笔记(一)【安装与使用】PostCSS自学笔记(二)【插件】PostCSS自学笔记(二)【专题一】PostCSS自学笔记(二)【专题二】
