PostCSS 常用外掛與語法介紹

NingBo發表於2019-04-03

前言

兩年前自己就開始學習 PostCSS ,但在開發中使用卻不到一年。
沒有使用的原因是覺得 PostCSS 外掛太多,學習成本很高。
但在開發中實際使用後,覺得 PostCSS 還是有很大的便捷性,諸如自動補全瀏覽器字首這一功能就節省了很多時間,把繁瑣的工作交給了程式,心思都集中在程式碼邏輯上,會讓開發的過程輕鬆不少。

PostCSS 是什麼

PostCSS 是一個用 JavaScript 工具和外掛轉換 CSS 程式碼的工具。

  • PostCSS 是處理 CSS 的一個外掛體系;
  • 可以對 CSS 進行各種不同的轉換和處理;
  • 把繁瑣複雜的工作交由程式去處理;
  • 把開發⼈人員解放出來。

PostCSS 如何使用

  • PostCSS 一般不單獨使用,而是與已有的構建工具進行整合;
  • PostCSS 與主流的構建工具,如 Webpack、Grunt 和 Gulp 都可以進行整合;
  • 完成整合之後,選擇滿足功能需求的 PostCSS 外掛並進行配置。

PostCSS 常用外掛

PostCSS 的外掛數量很多,可以根據實際場景選擇不同的外掛。

PostCSS 有哪些外掛

PostCSS 外掛列舉

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);     
      } 
      複製程式碼
  • 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:鍵值對

相關文章