前言
兩年前自己就開始學習 PostCSS ,但在開發中使用卻不到一年。
沒有使用的原因是覺得 PostCSS 外掛太多,學習成本很高。
但在開發中實際使用後,覺得 PostCSS 還是有很大的便捷性,諸如自動補全瀏覽器字首這一功能就節省了很多時間,把繁瑣的工作交給了程式,心思都集中在程式碼邏輯上,會讓開發的過程輕鬆不少。
PostCSS 是什麼
PostCSS 是一個用 JavaScript 工具和外掛轉換 CSS 程式碼的工具。
- PostCSS 是處理 CSS 的一個外掛體系;
- 可以對 CSS 進行各種不同的轉換和處理;
- 把繁瑣複雜的工作交由程式去處理;
- 把開發⼈人員解放出來。
PostCSS 如何使用
- PostCSS 一般不單獨使用,而是與已有的構建工具進行整合;
- PostCSS 與主流的構建工具,如 Webpack、Grunt 和 Gulp 都可以進行整合;
- 完成整合之後,選擇滿足功能需求的 PostCSS 外掛並進行配置。
PostCSS 常用外掛
PostCSS 的外掛數量很多,可以根據實際場景選擇不同的外掛。
PostCSS 有哪些外掛
- 外掛查詢地址:www.postcss.parts/
- 常⽤用外掛列列表:github.com/postcss/pos…
PostCSS 外掛列舉
- Autoprefixer:自動補全瀏覽器私有字首
- precss:CSS 預處理(整合 Sass、LESS 或 Stylus 功能,語法基本和 Sass 的相同)
- postcss-import:通過 @import,整合多個 CSS 檔案
- css-mqpacker:將相同的 CSS 媒體查詢規則合併為一個
- cssnano:壓縮 CSS 檔案
- postcss-color-rgba-fallback:給 rgba 顏色建立降級方案(新增備用顏色)
- postcss-opacity:給 opacity 提供降級方案(給 IE 瀏覽器新增濾鏡屬性)
- node-pixrem:讓 IE8 ⽀持 rem 單位
- postcss-pseudoelements:將偽元素的
::
轉換為:
( IE8 不不⽀支援::
)
PostCSS 語法介紹
以下主要介紹 precss 外掛的語法,precss 外掛包含了 Autoprefixer 外掛與 postcss-preset-env 外掛。
Autoprefixer 外掛語法
Autoprefixer:自動補全瀏覽器私有字首,瀏覽器字首可以參考 CanIUse 。
/*原始碼*/
p{
transform: scale(1);
animation: ani 1s linear;
}
複製程式碼
/*編譯後程式碼*/
p{
-webkit-transform:scale(1);
transform:scale(1);
-webkit-animation:ani 1s linear;
animation:ani 1s linear;
}
複製程式碼
postcss-preset-env 外掛語法介紹
postcss-preset-env:支援現代的 css 語法。
-
重置標籤所有屬性
/*原始碼*/ a{ all: initial; } 複製程式碼
/*編譯後程式碼*/ a{ -webkit-animation:none 0s ease 0s 1 normal none running; -webkit-backface-visibility:visible; -o-border-image:none; …… } 複製程式碼
-
統一錨點各狀態的樣式
/*原始碼*/ a:any-link{ background-color: yellow; } 複製程式碼
/*編譯後程式碼*/ a:-webkit-any-link{ background-color:#ff0; } a:-moz-any-link{ background-color:#ff0; } a:link,a:visited{ background-color:#ff0; } 複製程式碼
-
自定義媒體查詢
/*原始碼*/ @custom-media --narrow-window (max-width: 30em); @media (--narrow-window) { } 複製程式碼
/*編譯後程式碼*/ @media (max-width: 30em) { } 複製程式碼
-
自定義常量
/*原始碼*/ :root{ --some-length: 32px; } p{ height: var(--some-length); width: var(--some-length); } 複製程式碼
/*編譯後程式碼*/ :root{ --some-length:32px; } p{ height:32px; height:var(--some-length); width:32px; width:var(--some-length); } 複製程式碼
-
自定義選擇器
/*原始碼*/ @custom-selector :--heading h1, h2, h3, h4, h5, h6; :--heading { margin-block: 0; } 複製程式碼
/*編譯後程式碼*/ h1,h2,h3,h4,h5,h6{ margin-top:0; margin-bottom:0; } 複製程式碼
-
支援巢狀規則
/*原始碼*/ article{ &p{ color: #333; } } 複製程式碼
/*編譯後程式碼*/ article p { color: #333; } 複製程式碼
-
overflow 簡寫
/*原始碼*/ html{ overflow: hidden auto; } 複製程式碼
/*編譯後程式碼*/ html{ overflow-x:hidden; overflow-y:auto; overflow:hidden auto; } 複製程式碼
precss 外掛語法介紹
precss 支援類似sass語法,並支援未來語法,包含 postcss-preset-env 元件。
- 巢狀可以使用
&
符,把父選擇器複製到子選擇器中/*原始碼*/ article { margin-top: 20px; &p{ color: #333; } } 複製程式碼
/*編譯後程式碼*/ article{ margin-top:20px; } article p{ color:#333; } 複製程式碼
- 使用
$
符宣告變量/*原始碼*/ $text_color: #232323; $border_comn: 1px solid red; body{ color: $text_color; border: $border_comn; } 複製程式碼
/*編譯後程式碼*/ body{ color:#232323; border:1px solid red; } 複製程式碼
- 用
@if
和@else
來控制迴圈/*原始碼*/ $column_layout: 2; .column{ @if $column_layout == 2{ width: 50%; float: left; }@else{ width: 100%; } } 複製程式碼
/*編譯後程式碼*/ .column{ width:50%; float:left; } 複製程式碼
- 用
@for
和@each
來迴圈- @for 迴圈:⽤用⼀一個計數器器變數量,來設定迴圈的週期
/*原始碼*/ @for $i from 1 to 5{ p:nth-of-type($i){ margin-left: calc(100% / $i); } } 複製程式碼
/*編譯後程式碼*/ p:first-of-type{ margin-left:100%; } p:nth-of-type(2){ margin-left:50%; } p:nth-of-type(3){ margin-left:33.33333%; } p:nth-of-type(4){ margin-left:25%; } p:nth-of-type(5){ margin-left:20%; } 複製程式碼
/*原始碼*/ @for $count from 1 to 5 by 2 { .col-$count { width: $count%; } } 複製程式碼
/*編譯後程式碼*/ .col-1{ width:1%; } .col-3{ width:3%; } .col-5{ width:5%; } 複製程式碼
- @each 迴圈:迴圈週期是⼀一個列列表,⽽而不不是數字
/*原始碼*/ $social: twitter,facebook,youtube; @each $icon in ($social){ .icon-$(icon){ background: url('img/$(icon).png'); } } 複製程式碼
/*編譯後程式碼*/ .icon-twitter{ background:url(img/twitter.png); } .icon-facebook{ background:url(img/facebook.png); } .icon-youtube{ background:url(img/youtube.png); } 複製程式碼
- @for 迴圈:⽤用⼀一個計數器器變數量,來設定迴圈的週期
- mixin 建立 css 模板函式
- 通過
@mixin mixin_name($arg1, $arg2) {...}
來宣告 - 使用
@include mixin_name($arg1, $arg2)
來呼叫/*原始碼*/ @mixin heading-text($color: #242424, $font-size: 4em) { color: $color; font-size: $font-size; } h1, h2, h3 { @include heading-text; } .some-heading-component>:first-child{ @include heading-text(#111111, 6em); } 複製程式碼
/*編譯後程式碼*/ h1,h2,h3{ color:#242424; font-size:4em; } .some-heading-component>:first-child{ color:#111; font-size:6em; } 複製程式碼
- 通過
- 通過 @extend 建立 css 模板
/*原始碼*/ %thick-border { border: thick dotted red; } .modal { @extend %thick-border; color: red; } 複製程式碼
/*編譯後程式碼*/ .modal{ border:thick dotted red;color:red; } 複製程式碼
- @at-root 生成程式碼到根部
/*原始碼*/ .parent { font-size: 20px; @at-root{ .child { font-size: 25px; } } } 複製程式碼
/*編譯後程式碼*/ .child{ font-size:25px; } .parent{ font-size:20px; } 複製程式碼
- 直接引⽤用css屬性的值,例如@color
/*原始碼*/ .Test { margin-left: 20px; margin-right: @margin-left; color: red; background: @color url('test.png'); line-height: 1.5; font-size: @(line-height)em; } 複製程式碼
/*編譯後程式碼*/ .Test{ margin-left:20px; margin-right:20px; color:red; background:red url(test.png); line-height:1.5; font-size:1.5em; } 複製程式碼
自定義 PostCSS 元件
一個 PostCSS 外掛最基礎的構成如下:
var postcss = require('postcss');
module.exports = postcss.plugin('PLUGIN_NAME', function (opts) {
opts = opts || {};
// 傳⼊入配置相關的程式碼
return function (root, result) {
// 轉化CSS 的功能程式碼
};
});
複製程式碼
然後按照不同的需求情況來決定是否引入第三方模組,是否有額外配置項,最後在包含 root,result 的匿名函式中進行最為核心的轉換程式碼功能編寫。
- root(css):也是整個 CSS 程式碼段,包含多個 rule;
- rule:包含一個 CSS class 範圍內的程式碼段;
- nodes:代指 rule 中 {} 中間的多個 decl 部分;
- decl:單行 CSS ,即有屬性與值的部分;
- prop value:鍵值對