本文将会介绍 PostCSS 以及常用插件和 插件的编写方式
PostCSS是什么?
或许,你会认为它是预处理器、或者后处理器等等。其实,它什么都不是。它可以理解为一种插件系统。GitHub主页上的PostCss介绍为:
PostCSS 是一个允许使用 JS 插件转换样式的工具。 这些插件可以检查(lint)你的 CSS,支持 CSS Variables 和 Mixins, 编译尚未被浏览器广泛支持的先进的 CSS 语法,内联图片,以及其它很多优秀的功能。
常用插件介绍
- rucksack
rucksack 是 一个具有如下特点的 postcss 插件
- 响应式的字体布局
- 快速定位语法
- 原生的清除浮动的语法
- 自定生成字体文件路径
- 额外的input伪元素
- RGBA的十六进制快捷方式
- 更多缓动功能
在webpack中使用 rucksack
- postcss-mixins
mixins插件就提供了自定义mixin的功能,借用官方示例
@define-mixin icon $network, $color: blue {
.icon.is-$(network) {
color: $color;
@mixin-content;
}
.icon.is-$(network):hover {
color: white;
background: $color;
}
}
@mixin icon twitter {
background: url(twt.png);
}
最终被转换成
.icon.is-twitter {
color: blue;
background: url(twt.png);
}
.icon.is-twitter:hover {
color: white;
background: blue;
}
mixins插件使用时必须配置在postcss-simple-vars 和 postcss-nested的前面,下面就看一下这两个插件又是做什么的
- postcss-simple-vars
用来像sass那样支持变量使用的插件,选择符、值以及规则参数都可以使用变量.借用官方示例
$dir: top;
$blue: #056ef0;
$column: 200px;
.menu_link {
background: $blue;
width: $column;
}
.menu {
width: calc(4 * $column);
margin-$(dir): 10px;
}
最终会转成
.menu_link {
background: #056ef0;
width: 200px;
}
.menu {
width: calc(4 * 200px);
margin-top: 10px;
}
- postcss-nested
支持Sass 嵌套规则的写法,官方示例
.phone {
&_title {
width: 500px;
@media (max-width: 500px) {
width: auto;
}
body.is_dark & {
color: white;
}
}
img {
display: block;
}
}
最终会转成
.phone_title {
width: 500px;
}
@media (max-width: 500px) {
.phone_title {
width: auto;
}
}
body.is_dark .phone_title {
color: white;
}
.phone img {
display: block;
}
- postcss-next
提供转换最新css语法的功能
postcss 插件编写
插件究竟干了啥,值得我们研究,其实感觉和babel 的插件机制类似但又不一样,写起来相对更加简单。 以rucksack-css这个插件为例 ,他有一个功能就是让你定义一些自己的属性别名
@alias{
bd: border;
bg: background;
bg-i: background-image;
bg-c: background-color;
bg-p: background-position;
bg-s: background-size;
bg-o: background-origin;
l-h: line-height;
t-a: text-align;
}
类似这样 让你写更少的代码他去帮你编译 ,那它是如何实现这中黑魔法的,我们来一探究竟 我们把ta:center转换成 text-aligin:center
const postcss = require('postcss');
const less = require("less");
// 要转换的语法
const parseProps = {
ta:'text-align'
}
// 策略模式转换语法
const parseRules = (rule,props)=> {
if(parseProps[props]){
rule['nodes'][0]['prop'] = parseProps[props];
}
}
//定义插件
const postcssPlugin = postcss.plugin("postcssPlugin", (opts) => {
// 在这里配置你的选项
opts = opts || {};
return root => {
// root.walkRules 遍历容器的后代节点,为每个规则节点调用回调,如果传递过滤器,迭代将仅发生在具有匹配选择器的规则上。
root.walkRules((rule)=>{
parseRules(rule,rule['nodes'][0]['prop'])
});
};
});
postcss([postcssPlugin])
.process(`a{
ta : center;
}`, {
parser: less.parser,
from: './style.less',
}).then((css)=>{
// 转换后的内容
console.log(css);
})
整个代码就这些 当然你的插件也可以依赖别人的插件
欢迎关注我的公众号FE未道 ,不间断更新, 我们一起脚踏实地,仰望星空。