記一次postcss分享總結

最近在公司給同事們分享了一下postcss,在這裏作一個簡單總結:css

在咱們平常寫css的過程當中,通常會有哪些以爲比較繁瑣的地方??
這裏我列舉我本身平常開發中以爲比較繁瑣的幾點:css3

  • 前綴問題;
  • 有時候爲了規範或是精確性咱們會寫一些比較深的選擇器;
  • 在不肯定一些css屬性兼容性的時候,咱們常常須要查詢一些屬性的瀏覽器兼容性;

上面提到的問題,postcss中都有相應的插件能夠幫咱們解決對應的問題,下面的問題是,postcss是什麼?git

在看一些講postcss的文章裏,會說明postcss不是相似sass、less的預處理器,也不是後處理器,那postcss究竟是什麼?這時候。。。直接看API:github

clipboard.png

上面列舉的是api中一些基本的類說明(詳細api移步:http://api.postcss.org/),結合postcss文檔中說明的postcss的工做流:web

workflow:

clipboard.png

Core Structor

clipboard.png

總結說明:
postcss處理css的方式,主要區分三部分:npm

  • parser過程:將css字符串解析成可供咱們操做的JavaScript對象
  • processor過程:咱們應用postcss插件、或是自定義插件,都是在這個過程當中,根據postcss提供的API,對parser生成的js對象作相應調整;
  • stringfier過程:將咱們處理後的js對象,再轉換回爲css字符串

下面經過具體的代碼說明一下postcss 對css的轉換:
npm 安裝postcss、代碼以下:json

var postcss = require('postcss')
var root    = postcss.parse('a{color:white;} b{width:100px}')

返回的root對象的內容爲下圖:gulp

clipboard.png

由上圖能夠看到,root對象是咱們css代碼結構化生成的js對象,裏邊對應包含咱們的選擇器、css屬性名、屬性值等等(圖中標示了一些很容易理解的信息,想要了解詳細能夠移至官方api:http://api.postcss.org/),通過這一步以後,咱們能夠操做這個js對象,作出一切咱們想要的改變,而後再由stringfile轉換爲最終的css代碼。小程序

有了上面這些,在使用postcss的時候,就有了一些基本的認知。下面介紹幾款經常使用的插件:api

插件

Autoprefixer:

這應該是postcss最廣爲人知的一個插件了 ,這個插件能夠:

  • 能夠指定瀏覽器版本、範圍

    • 在插件參數中指定
    • use .browserslistrc config
    • package.json with browserslist key
  • 去除過期的前綴

precss

這款插件相似less、sass ,可讓咱們在css中使用變量、css嵌套、函數、mixin
除了precss,還有不少細粒度的插件,好比:

  • postcss-nested:專門支持css嵌套寫法:
  • postcss-define-function :實現相似sass 函數功能
  • postcss-for:專門增長循環支持
  • ...

doiuse:

能夠爲咱們檢查瀏覽器支持

cssnano:

css壓縮(會進行一些合併轉換操做 ,示例會說明)

詳細插件列表及分類,請移至:https://github.com/postcss/po...

代碼示例:
說明:示例基於gulp+gulp-postcss
npm安裝好gulp、gulp-postcss以及對應的插件,下面的實例使用到postcss-nested、cssnano、postcss-apply、autoprefixer、gulp-rename

gulpfile.js:

var gulp=require('gulp')
var postcss=require('gulp-postcss')
var nested=require('postcss-nested')
var cssnano=require('cssnano')
var apply=require('postcss-apply')
var autoprefixer=require('autoprefixer')
var rename=require('gulp-rename')

var option={
  browsers: ['Opera 12', 'IE 8']
}

gulp.task('postcss',function() {
  return  gulp.src('./test.pcss').pipe(postcss([autoprefixer(option),apply,nested])).on('error',function(error) {
    console.log(error)
    this.end()
  }).pipe(rename({extname:'.css'})).pipe(gulp.dest('./'))
})

上面咱們指定使用的瀏覽器,只是示例,使用'Opera 12', 'IE 8'這樣的組合,咱們的源文件爲test.pcss(這裏我使用webstorm安裝了postcss相關插件,.pcss後綴表示postcss樣式文件,避免編輯器的語法錯誤提示),使用gulp-rename插件,最終生成的文件爲當前目錄下的test.css,執行任務,這裏貼出源文件與生成後的文件對比:

clipboard.png

由上面的對比,咱們能夠看出autoprefixer 自動增長/刪除(固然也能夠設置不刪除) 前綴的功能,以及嵌套等的使用,下面一個問題:關於瀏覽器的兼容性檢查呢?
使用doiuse,代碼以下:

gulp.task('doiuse',function() {
  var option={
    browsers: [
      'ie >= 6',
    ],
    onFeatureUsage: function (usageInfo) {
      console.log(usageInfo.message)
    }
  }
  gulp.src('./test.css').pipe(postcss([doiuse(option)]))
})

給出運行結果的部分截圖:

clipboard.png

這裏咱們選擇的瀏覽器範圍是‘ie>=6’,doiuse執行的結果會告訴咱們css3 transition 並不被ie一些版本的瀏覽器支持。這樣咱們就能夠精確、統一地爲咱們的css進行瀏覽器兼容檢查。

最後一步:壓縮:
代碼:

gulp.task('cssnano',function() {
  gulp.src('./test.css').pipe(postcss([cssnano])).pipe(gulp.dest('./'))
})

上面test.css文件生成的結果以下:

clipboard.png

這裏提醒你們注意的是,咱們本來css文件中,樣式分開寫的部分,cssnano爲咱們作了合併操做,顏色屬性的屬性值部分,也換成了字節數比較少的16進製表示法。爲咱們的css文件減小了一部分大小。

寫一個插件

對於插件的編寫文檔也很詳細,這裏給一個本身平常用的簡單示例,最近在寫一個小程序項目,寫小程序樣式時使用一個單位:rpx,結合平常的編碼習慣,寫這個單位以爲異常彆扭,因而寫了一個針對特定屬性自動加單位的插件,代碼以下:在gulpfile.js裏增長以下代碼:

function addunit(root) {
  // Transform CSS AST here
  var needAddProperties = ['width', 'height', 'top', 'left', 'bottom', 'right', 'margin-top',
                           'margin-bottom', 'margin-left', 'margin-right',
                           'padding-right', 'padding-left', 'padding-top', 'padding-bottom']
  root.walkDecls(function(decl) {
    if (needAddProperties.indexOf(decl.prop)!= -1) {
      decl.value.indexOf('%')== -1 && decl.value.indexOf('rpx')== -1 && (decl.value += 'rpx')
    }
  })
}

gulp任務中 postcss插件數組末尾增長一個本身寫的插件 addunit:

gulp.task('postcss', function() {
  return gulp.src('./testaddunit.pcss').pipe(postcss([autoprefixer(option), apply, nested, addunit]))
             .on('error', function(error) {
    console.log(error)
    this.end()
  }).pipe(rename({ extname : '.css' })).pipe(gulp.dest('./'))
})

處理文件的先後對好比下:

clipboard.png

處理過程會根據須要自動爲咱們添加單位。在實際開發中再配合postcss-scrib,咱們是能夠這樣寫代碼的:

clipboard.png

這裏使用postcss-scrib插件咱們能夠爲屬性自定義別名,結合gulp的watch功能,實時爲咱們生成對應的css文件,也沒有了編輯器語法錯誤提示,寫css一會兒美好了不少。。。

end

相關文章
相關標籤/搜索