一、PostCSS 是什么?
PostCSS 将 CSS 转换为 JavaScript 可以操作的数据结构,这些数据可以由插件理解和转换,然后处理成各种需要的格式。
PostCSS并不是一门语言,而是一个类似于webpack的工具,它支持很多插件,来达到便捷的编译效果,组成一个CSS编译/lint/autoprefixer的生态圈。
PostCSS 本身是一个功能比较单一的工具。它提供了一种方式用 JavaScript 代码来处理 CSS。它负责把 CSS 代码解析成抽象语法树结构(Abstract Syntax Tree,AST),再交由插件来进行处理。
插件基于 CSS 代码的 AST 所能进行的操作是多种多样的,比如可以支持变量和混入(mixin),增加浏览器相关的声明前缀,或是把使用将来的 CSS 规范的样式规则转译(transpile)成当前的 CSS 规范支持的格式。从这个角度来说,PostCSS 的强大之处在于其不断发展的插件体系。
目前 PostCSS 已经有 200 多个功能各异的插件。开发人员也可以根据项目的需要,开发出自己的 PostCSS 插件。
实际上,PostCSS 的主要功能只有两个:
第一个就是前面提到的把 CSS 解析成 JavaScript 可以操作的 AST。
第二个就是调用插件来处理 AST 并得到结果。
因此,不能简单的把 PostCSS 归类成 CSS 预处理或后处理工具。PostCSS 所能执行的任务非常多,同时涵盖了传统意义上的预处理和后处理。
二、PostCSS 和 CSS预处理器的区别
PostCSS的一大特点是,具体的编译插件甚至是CSS书写风格,可以根据自己的需要进行安装,选择自己需要的特性:嵌套,函数,变量。自动补全,CSS新特性等等,而不是像less或者scss一样的大型全家桶。因此,不需要再专门去学习less或者scss的语法,只要选择自己喜欢的特性,可以只写 CSS 文件,但依旧可以写嵌套或者函数,然后选择合适的插件编译它就行了。
三、有什么用?
- 可以检查(lint)你的 CSS
- 支持 CSS Variables 和 Mixins
- 编译尚未被浏览器广泛支持的先进的 CSS 语法
- 内联图片
- 模块化css
- css in js
- ...
四、webpack 中怎么使用 PostCSS
- 依赖于 node.js
- 引入 postcss
npm install postcss -D
npm install postcss-loader -D
- 引入一些需要的插件
# eg:添加浏览器CSS兼容性前缀(如-webkit、-moz)的插件
npm install autoprefixer -D
- webpack 配置 loader(ps:可以直接在配置
loader的地方配置options,也可以添加postcss.config.js配置文件配置options)
{
loader: 'postcss-loader',
options: {
postcssOptions: {
plugins: [
// autoprefixer插件:添加了 vendor 浏览器前缀。
autoprefixer({
// 适配99%的浏览器,最新两个版本
overrideBrowserslist: ['> 1%', 'last 2 versions', 'not ie <= 8'],
}),
]
},
},
};
五、常见 PostCSS 插件
- autoprefixer: 给css属性添加兼容性前缀
- postcss-import: 合并样式
- cssnano: 压缩css代码
- postcss-preset-env: 允许你使用一些新的的css特性
- postcss-html:它可以将html文件中的样式块中的CSS代码提取出来进行处理,这样可以使CSS代码更加集中、维护更简单
六、自定义一个 PostCSS 插件
- Root:PostCss处理过的Css,整个处理过程基本上都在围绕着Root。Commont,AtRule,Rule都是它的子节点。
- AtRule:为带@标识的部分,name为标识名称,params为标识参数。nodes为内部包含的其他子节点,可以是Commont,AtRule,Rule,这让我们可以自定义更多的规则
- Rule:选择器样式部分,一个选择器代表一个Rule,选择器对应的样式列表nodes为Declaration构造函数
- Declaration:为CSS样式属性,prop为样式属性,value为样式值。可给Rule手动添加样式属性,也可以修改prop,value。
module.exports = (opts = { }) => {
// 此处可对插件配置opts进行处理
return {
postcssPlugin: 'postcss-test', // 插件名字,以postcss-开头
Once (root, postcss) {
// 此处root即为转换后的AST,此方法转换一次css将调用一次
},
Declaration (decl, postcss) {
// postcss遍历css样式时调用,在这里可以快速获得type为decl的节点(请参考第二节的AST对象)
},
Declaration: {
color(decl, postcss) {
// 可以进一步获得decl节点指定的属性值,这里是获得属性为color的值
// 下面的内容是把字体颜色替换了
if (decl.value === 'white') {
decl.value = 'green'
}
if (decl.value === 'red') {
decl.value = 'yellow'
}
}
},
Comment (comment, postcss) {
// 可以快速访问AST注释节点(type为comment)
},
AtRule(atRule, postcss) {
// 可以快速访问css如@media,@import等@定义的节点(type为atRule)
}
}
}
module.exports.postcss = true
将插件使用到 postcss 配置中?
plugins: [
// autoprefixer插件:添加了 vendor 浏览器前缀,它使用 Can I Use 上面的数据。
autoprefixer({
// 适配99%的浏览器,最新两个版本
overrideBrowserslist: ['> 1%', 'last 2 versions', 'not ie <= 8'],
}),
// 这里的url是自定义的插件的路径,{}是传入插件的参数
require('../src/tools/test-plugin')({})
]