pxtorem
pxtorem 是一个 PostCSS插件,可以把CSS单位px转成rem。
例如,对下面的例子,假设根元素(html)的字体大小是16px,那么对所有的px换算规则就是:y = x/16 rem:
/** input */
h1 {
margin: 0 0 20px;
font-size: 32px;
line-height: 1.2;
letter-spacing: 1px;
}
/** output */
h1 {
margin: 0 0 20px;
font-size: 2rem;
line-height: 1.2;
letter-spacing: 0.0625rem;
}
分析
pxtorem是一个PostCSS插件,所以在写法上要遵循PostCSS的规则,利用PostCSS提供的钩子和API,可以在每个钩子上方便的获取到CSS转成AST之后对应的结果。如下,是该插件的代码结构:
主要是分析Once和Declaration这两个钩子。
Once钩子
Once钩子是在根节点上执行,对于每个css文件都会执行一次。
pxtorem插件这个阶段里面做了:
判断当前文件是否在exclude包含的路径内(exclude是用户使用时提供的配置);
获取根元素字体大小;
-
给变量pxReplace赋值(px转为rem的函数);
createPxReplace比较简单,如下:
Declaration钩子
在所有声明节点上(color: black就是一个节点)调用和在节点或子级更改时再次调用。
当前文件是否不转化;
各种跳过转化的情况(不存在px 、属性不转化、选择器是否在需要被过滤的列表内);
-
把px转化成rem;
那上面的decl.value = value 和 decl.cloneAfter({value: value})有什么区别呢?
decl.value是直接替换
ul { ul {
padding: 16px; => padding: 1rem;
} }
cloneAfter会在下方多加一行代码:
ul { ul {
padding: 16px; => padding: 16px;
padding: 1rem;
} }
Q & A
为什么PX这种写法能被忽略转化:
官方问题提出最简单的忽略转化的方法是把px写成Px或者PX:
在代码里面,可以看到判断px是通过indexOf('px')来精确判断的:
结尾
PostCSS插件对大多数人来说是不需要自己去写的,现在有大量的PostCSS插件基本上覆盖了你需要的场景。但是我们可以了解下这个知识点,以后跳槽也有东西讲。