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之后對應的結果。如下,是該插件的代碼結構:
image.png
主要是分析Once和Declaration這兩個鉤子。
Once鉤子
Once鉤子是在根節點上執行,對于每個css文件都會執行一次。
pxtorem插件這個階段里面做了:
判斷當前文件是否在exclude包含的路徑內(exclude是用戶使用時提供的配置);
獲取根元素字體大小;
-
給變量pxReplace賦值(px轉為rem的函數);
image.png
createPxReplace比較簡單,如下:
image.png
Declaration鉤子
在所有聲明節點上(color: black就是一個節點)調用和在節點或子級更改時再次調用。
當前文件是否不轉化;
各種跳過轉化的情況(不存在px 、屬性不轉化、選擇器是否在需要被過濾的列表內);
-
把px轉化成rem;
image.png
那上面的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')來精確判斷的:
image.png
結尾
PostCSS插件對大多數人來說是不需要自己去寫的,現在有大量的PostCSS插件基本上覆蓋了你需要的場景。但是我們可以了解下這個知識點,以后跳槽也有東西講??。