postcss-pxtorem插件是如何把px轉成rem的?

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插件這個階段里面做了:

  1. 判斷當前文件是否在exclude包含的路徑內(exclude是用戶使用時提供的配置);

  2. 獲取根元素字體大小;

  3. 給變量pxReplace賦值(px轉為rem的函數);


    image.png

createPxReplace比較簡單,如下:


image.png

Declaration鉤子

在所有聲明節點上(color: black就是一個節點)調用和在節點或子級更改時再次調用。

  1. 當前文件是否不轉化;

  2. 各種跳過轉化的情況(不存在px 、屬性不轉化、選擇器是否在需要被過濾的列表內);

  3. 把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插件基本上覆蓋了你需要的場景。但是我們可以了解下這個知識點,以后跳槽也有東西講??。

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容