如果你喜歡使用PostCSS,但又不想拋棄你最喜歡的預處理器。不用擔心,你不需要作出二選一的選擇,你可以把PostCSS和預處理器(Sass、Stylus或LESS)結合起來使用。
有幾個PostCSS插件配合預處理器得到很好的贊譽,因為他們將功能添加到你的工作流中,讓你工作變得更加輕松。如果你只使用一個預處理器,而不使用這些插件,你的工作流至少會變得更加困難。
我們會涉及一些免費的PostCSS插件,然后我們將會介紹一些配置的闡述,告訴您如何將PostCSS和你喜歡的預處理器(Sass、Stylus或LESS)之一結合在一起使用。
為什么要使用兩個?
在我們開始介紹如何要把預處理器和PostCSS一起使用,我們將談一談為什么你會這么想。簡短的答案是:PostCSS插件有很多優秀的預處理器功能。下面的內容會向你們展示為什么這些PostCSS插件是值得擁有的,而且這些插件和預處理器結合在一起工作會變得更好。
注意:在常規的預處理器通過使用混合宏或函數特性像程序一樣處理代碼,但下面的例子是自動處理的,也能達到類似的結果。不過不同的是,你關心的是編寫你自己的CSS代碼,而其他一切通過插件去處理,而這個過程中不需要調用函數,也沒有混合宏等等。
Autoprefixer
預處理器中有很多混合宏處理瀏覽器前綴。比如說,Compass庫中使用@include box-sizing(border-box);
來解決box-sizing
屬性在各瀏覽器的私有前綴。
依靠混合宏處理瀏覽器私有前綴,會存在下面這些問題:
- 要知道屬性需要的前綴,然后才能決定如何部署混合宏
- 必須知道混合宏的名稱和如何調用混合宏
- 必須時刻關注瀏覽器對每個屬性的私有前綴變化(比如,
box-sizing
現在就不再需要前綴)
Autoprefixer消除了對這些方面的擔憂,它可以根據CanIUse.com數據對屬性自動添加瀏覽器的私有前綴。
有關於Autoprefixer更詳細的信息可以點擊這里。
rtlcss
預處理器可以根據來源在樣式中生成LTR
(left
向right
,這也是默認的)和RTL
(right
向left
),但它通常需要使用一些混合宏或變量插值。例如,你要寫margin-left:1rem
,你可能需要編寫margin-#{$dir}:1rem;
或@include margin-left(1rem);
。
然而,@Mohammad Younes開發的rtlcss插件,你不需要再使用混合宏或變量插值。你平時只要按正常的編寫方式編寫CSS,插件會自動根據所有實例,完成right
或left
的互換。你不需要編寫任何特殊代碼,就可以讓margin-left:1rem;
會自動生成margin-right:1rem;
。
postcss-colorblind
由@Brian Holt提供的postcss-colorblind插件可以自動生成不同版本的樣式表,讓你不懂色彩的人也能親身體驗自己的設計。這款插件模擬了八種不同類型的顏色配色方案,可以快速訪問你的配色方案。
這是PostCSS插件的一個有用功能,而這個功能在預處理器中要實現是非常困難的。
有關於postcss-colorblind相關的信息可以點擊這里。
postcss-svgo
@Ben Briggs的postcss-svgo插件可以給內聯SVG的代碼做優化,例如:
background: url('data:image/svg+xml;utf-8,<?xml version="1.0" encoding="utf-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve"><circle cx="50" cy="50" r="40" fill="yellow" /></svg>');
優化后的代碼不到原來的一半:
background: url('data:image/svg+xml;utf-8,<svg xmlns="http://www.w3.org/2000/svg"><circle cx="50" cy="50" r="40" fill="#ff0"/></svg>');
有關於postcss-svgo插件更多的信息可點擊這里。
cssnano
雖然預處理器中可以帶空格和注釋,但@Ben Briggs的cssnano插件可以執行的各種優化遠遠超過這兩個步驟。本系列教程中的《PostCSS深入學習: 壓縮和優化CSS》詳細討論了如何使用cssnano對你的樣式表進行優化和壓縮。
postcss-font-magician
@Jonathan Neal的postcss-font-magician插件可以讓你非常容易的使用自定義字體。你不需要使用任何混合宏之類,只需要像平時那樣使用font-family
規則就行:
body { font-family: "Alice"; }
插件會生成一份完整的@font-face
規則:
@font-face { font-family: "Alice"; font-style: normal; font-weight: 400; src: local("Alice"), local("Alice-Regular"), url("http://fonts.gstatic.com/s/alice/v7/sZyKh5NKrCk1xkCk_F1S8A.eot?#") format("eot"), url("http://fonts.gstatic.com/s/alice/v7/l5RFQT5MQiajQkFxjDLySg.woff2") format("woff2"), url("http://fonts.gstatic.com/s/alice/v7/_H4kMcdhHr0B8RDaQcqpTA.woff") format("woff"), url("http://fonts.gstatic.com/s/alice/v7/acf9XsUhgp1k2j79ATk2cw.ttf") format("truetype") } body { font-family: "Alice"; }
在關於postcss-font-magician更多信息可以點擊這里。
項目配置
下面有六個配置指南:每個主流預處理器(Sass、LESS或Stylus)分別結合Gulp或Grunt在項目中的配置指南。當然,你沒必要都看,你完全可以選擇你自己喜歡的預處理器和構建工具。如果你不能確定在項目中使用Gulp還是Grunt。那么本教程將會告訴你,Gulp是一個很好的選擇,因為其簡單。
無論你使用什么樣的項目配置指南,你都需要一個空的Gulp或Grunt的項目。你可以閱讀本系列教程中有關於Gulp或Grunt配置項目的相關教程:
如果你不想從頭開始手動設置您的項目,你可以下載本教程中提供的源碼附件,提取Gulp或Grunt項目到一個空的文件夾中。
然后在命令終端運行:npm install
。
項目中安裝PostCSS插件
當你為下面的小節設置了一個空的項目,你還需要安裝兩個PostCSS插件:Autoprefixer和cssnano。你可以通過下面的命令來安裝:
npm install autoprefixer cssnano --save-dev
我們將用這兩個插件來測試你的預處理器和PostCSS一起工作。
預處器在PostCSS之前運行
使用預處理器和PostCSS一起處理你的樣式表,首要的原則是:預處理器要運行在PostCSS之前。這主要是因為你不想讓任何預處理器的指定語法讓PostCSS插件癱瘓不能工作,當然也不希望PostCSS修改你的代碼,防止預處理器不能按預期運行。
PostCSS插件和PostCSS測試代碼
在開始介紹每個預處理器和PostCSS一起工作的配置之前,我們都會讓預處理器編譯完成之后再運行PostCSS插件Autoprefixer和cssnano。在每個配置介紹中,我們都需要為這兩個插件添加一些測試代碼。
為了在每個小節中節省重復相同的代碼,當你看到說讓你添加PostCSS測試代碼這樣的指令時,請在預處理器源文件中添加下面的代碼:
.css_nano, .css_nano + p, [class*="css_nano"], .css_nano { /* cssnano will remove this comment */ display: flex; font-weight: normal; margin-top: 1rem; margin-bottom: 2rem; margin-left: 1.5rem; margin-right: 2.5rem; font-weight: normal; padding: 1.75rem; width: calc(50rem - (2 * 1.75rem)); }
如果成功了,每個示例編譯出來的代碼如下:
.css_nano,.css_nano+p,[class*=css_nano]{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;margin:1rem 2.5rem 2rem 1.5rem;font-weight:400;padding:1.75rem;width:46.5rem}
注意:使用Autoprefixer給flexbox添加私有前綴和使用cssnano來優化和壓縮你的樣式表。我們使用相同的代碼來測試cssnano,正如前面的教程《PostCSS深入學習: 壓縮和優化CSS》所介紹的一樣,所以你可以參考前面的教程了解其中執行優化和壓縮的細節。
Sass和PostCSS
因為你已經使用了Node.js來運行Gulp或Grunt和PostCSS,所以使用Sass最簡單的方法就是使用LibSass。而且LibSass編譯速度也要比Ruby Sass快很多。在下面的教程中,將通過gulp-sass或grunt-contrib-sass模塊來部署LibSass。
通過Gulp來配置
使用npm install gulp-sass --save-dev
將gulp-sass模塊安裝到你的項目中。
接下來像下面一樣更新你的gulpfile.js
文件:
var gulp = require('gulp'); var postcss = require('gulp-postcss'); var sass = require('gulp-sass'); var autoprefixer = require('autoprefixer'); var cssnano = require('cssnano'); gulp.task('css', function () { var processors = [ autoprefixer, cssnano ]; return gulp.src('./src/*.scss') .pipe(sass().on('error', sass.logError)) .pipe(postcss(processors)) .pipe(gulp.dest('./dest')); });
修改了默認的gulpfile.js
文件:
- 添加變量,加載
gulp-sass
,autoprefixer
和cssnano
- 將
autoprefixer
和cssnano
變量放在processors
數組內 - 將要編譯的源文件名
.css
的擴展名修改為.scss
- 添加
pipe()
,.pipe(sass()...)
用來處理Sass,需要確保的是處理Sass要放在PostCSS前面
現在我們可以寫一些測試代碼來確保Sass和PostCSS都能正常編譯。
測試預處理器
將src/style.css
文件重命名為src/style.scss
,並且在文件中添加下面的測試代碼:
$font-stack: Helvetica, sans-serif; $primary-color: #333; body { font: 100% $font-stack; color: $primary-color; }
運行gulp css
,並且看看dest/
中有沒有一個新文件style.css
,並且文件中的內容:
body { font: 100% Helvetica, sans-serif; color: #333; }
測試PostCSS
現在,在style.scss
文件中添加前面提供測試PostCSS的代碼。並且運行gulp css
之后,查看dest/style.css
文件:
body{font:100% Helvetica,sans-serif;color:#333}.css_nano,.css_nano+p,[class*=css_nano]{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;margin:1rem 2.5rem 2rem 1.5rem;font-weight:400;padding:1.75rem;width:46.5rem}
通過Grunt來配置
使用npm install grunt-contrib-sass
在你新的Grunt項目中安裝grunt-contrib-sass
模塊。
然后在grunt.loadNpmTasks()
函數中添加grunt-contrib-sass
,放在之前PostCSS的后面:
grunt.loadNpmTasks('grunt-postcss');
grunt.loadNpmTasks('grunt-contrib-sass');
現在需要設置一個新的任務來處理Sass:
grunt.initConfig({
但是需要在postcss
任務前添加這段代碼:
sass: { dist: { files: { 'src/style.css': 'src/style.scss' } } },
現在已經注冊好了Sass和PostCSS任務。之后需要在grunt.loadNpmTasks()
函數中插入這些任務:
grunt.registerTask('css', ['sass', 'postcss']);
測試預處理器
將src/style.css
文件重新命名為src/style.scss
,並且添加下面的Sass代碼,來測試你的配置:
$font-stack: Helvetica, sans-serif; $primary-color: #333; body { font: 100% $font-stack; color: $primary-color; }
運行grunt css
命令之后,在dest/
文件夾中會創建一個新文件style.css
,編譯后的代碼將放在這個文件中:
body { font: 100% Helvetica, sans-serif; color: #333; }
設置PostCSS
現在我們需要運行autoprefixer
和cssnano
插件,在你的gruntfile.js
文件中的processors
數組中添加下面代碼:
processors: [ require('autoprefixer')(), require('cssnano')() ]
測試PostCSS
將測試PostCSS的代碼添加到style.scss
文件中,然后在命令中再次運行grunt css
命令,你會在dest/style.css
中看到編譯后的代碼,編譯后的代碼包括了autoprefixer
處理后的代碼,並且整個代碼進行了壓縮和優化。
Stylus和PostCSS
首先得非常感謝@Sean King提供的PostStylus的插件包,它能讓你將Stylus和PostCSS很好的結合在一起工作。如果你是一名Stylus開發者,你可以將PostStylus添加到你的工作流中。
通過Gulp來配置
如果你正在使用一個半成品的gulpfile.js
來啟動你的項目,需要注意的是,里面使用了gulp-postcss
插件。而實際上是只有使用Sass的才需要在流程添加這個插件,但對於使用Stylus的同學來說,這個插件是不需要的,我們要使用的是PostStylus插件包作為編譯器。
使用npm uninstall gulp-postcss --save-dev
刪除它,並且將gulpfile.js
文件中的這行代碼刪除掉:
var postcss = require('gulp-postcss');
接下需要安裝Stylus和PostCSS插件,你可以在命令行中執行下面的命令:
npm install gulp-stylus poststylus --save-dev
並且將gulpfile.js
文件更新為:
var gulp = require('gulp'); var stylus = require('gulp-stylus'); var poststylus = require('poststylus'); var autoprefixer = require('autoprefixer'); var cssnano = require('cssnano'); gulp.task('css', function () { var processors = [ autoprefixer, cssnano ]; return gulp.src('./src/*.styl') .pipe(stylus({ use: [ poststylus(processors) ] })) .pipe(gulp.dest('./dest')); });
上面的代碼主要執行:
- 添加
gulp-stylus
,poststylus
,autoprefixer
和cssnano
變量來加載這些插件 - 在
processors
數組中添加autoprefixer
和cssnano
變量 - 將要編譯的源文件名
.css
擴展名換成.styl
- 移除
.pipe()
行中的.pipe(postcss(processors))
- 在
.pipe()
行中添加.pipe(stylus{...})
來設置gulp-stylus
和poststylus
模塊的編譯功能
測試預處理器
開始首輪測試編譯。在src
目錄中,把style.css
文件重新命名為style.styl
,並且在文件中添加測試Stylus的代碼:
$font-stack = Helvetica, sans-serif $primary-color = #333 body font: 100% $font-stack color: $primary-color
運行gulp css
命令之后,你在dest/
目錄中能看到一個style.css
文件,並且帶有編譯后的代碼:
body { font: 100% Helvetica, sans-serif; color: #333; }
測試PostCSS
將前面提到測試PostCSS代碼添加到你的style.styl
文件中,確保粘貼后的代碼中只有tab
縮進,而沒有spaces
縮進。
重新編譯一下文件,檢查你的dest/style.css
文件,是否包含了編譯之后輸出的代碼:
body{font:100% Helvetica,sans-serif;color:#333}.css_nano,.css_nano+p,[class*=css_nano]{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;margin:1rem 2.5rem 2rem 1.5rem;font-weight:400;padding:1.75rem;width:46.5rem}
通過Grunt來配置
和使用Gulp配置Stylus的項目一樣,默認的PostCSS編譯器不是項目必需的,它只是純用於Sass和LESS這樣的處理器中。你可以通過npm uninstall grunt-postcss --save-dev
命令將其從你的項目中刪除。
現在,使用下面的命令將grunt-contrib-stylus
和poststylus
功能模塊安裝到你的項目中:
npm install grunt-contrib-stylus poststylus --save-dev
由於我們不需要再使用grunt-postcss
,所以將下面這行代碼:
grunt.loadNpmTasks('grunt-postcss');
換成:
grunt.loadNpmTasks('grunt-contrib-stylus');
因為不需要使用grunt-postcss
,所以在grunt.initConfig({...})
中就不再需要postcss
任務,所以得刪除掉這個任務,並且將stylus
任務替換上去:
stylus: {
compile: {
options: {
},
files: {
'dest/style.css': 'src/style.styl'
}
}
}
測試預處理器
現在我們已經准備好測試編譯器。把你的src
文件夾中的style.css
重命名為style.styl
,並且在這個文件中添加Stylus測試代碼:
$font-stack = Helvetica, sans-serif $primary-color = #333 body font: 100% $font-stack color: $primary-color
在命令行中執行grunt stylus
命令。你可以在dest/
文件夾中的style.css
文件中可以看到下面的代碼:
body{font:100% Helvetica,sans-serif;color:#333}
配置PostCSS
將PostCSS插件添加到項目的編譯過程中,首先將這段代碼添加到gruntfile.js
頂部,在module.exports...
上面:
var poststylus = function() { return require('poststylus')(['autoprefixer', 'cssnano']) };
在項目中加載你想要的PostCSS插件上,而不是像前面的教程一樣,放在一個processors
數組中。
應該在stylus
任務中添加options
對象,可以按下面的方式更新你的代碼:
options: { use: [poststylus] },
這是告訴grunt-contrib-stylus
使用poststylus
插件來編譯,當然你也可以在這個里面添加PostCSS的其他插件。
測試PostCSS
在src/style.styl
文件中添加PostCSS的測試代碼,然后在命令行中運行grunt stylus
命令。你在dest/style.css
文件中可以看到編譯后的代碼:
body{font:100% Helvetica,sans-serif;color:#333}.css_nano,.css_nano+p,[class*=css_nano]{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;margin:1rem 2.5rem 2rem 1.5rem;font-weight:400;padding:1.75rem;width:46.5rem}
LESS和PostCSS
通過Gulp來配置
通過npm install gulp-less --save-dev
把gulp-less
模塊安裝到你的項目中。
接下來需要更新gulpfile.js
文件的配置:
var gulp = require('gulp'); var postcss = require('gulp-postcss'); var less = require('gulp-less'); var autoprefixer = require('autoprefixer'); var cssnano = require('cssnano'); gulp.task('css', function () { var processors = [ autoprefixer, cssnano ]; return gulp.src('./src/*.less') .pipe(less()) .pipe(postcss(processors)) .pipe(gulp.dest('./dest')); });
默認的gulpfile.js
文件做了一些改變:
- 添加
gulp-less
、autoprefixer
和cssnano
變量加載這些模塊 - 在
processors
數組中添加autoprefixer
和cssnano
變量 - 將編譯源文件中的
.css
擴展名換成.less
- 在
.pipe()
添加LESS處理,並且放在PostCSS處理器前面
測試預處理器
接下來測試LESS和PostCSS。
將src/style.css
重命名為src/style.less
,並且在文件中添加下面的測試代碼:
@font-stack: Helvetica, sans-serif; @primary-color: #333; body { font: 100% @font-stack; color: @primary-color; }
運行gulp css
命令,在你的dest/
目錄中可以看到添加了一個style.css
文件,文件中包含了編譯后的代碼:
body{font:100% Helvetica,sans-serif;color:#333}
測試PostCSS
現在在你的style.less
文件中添加前面提供的PostCSS測試代碼。
運行gulp css
命令,編譯后的代碼添加到dest/style.css
文件中:
body{font:100% Helvetica,sans-serif;color:#333}.css_nano,.css_nano+p,[class*=css_nano]{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;margin:1rem 2.5rem 2rem 1.5rem;font-weight:400;padding:1.75rem;width:46.5rem}
通過Grunt來配置
在新的Grunt項目中通過npm install grunt-contrib-less
命令將grunt-contrib-less
模塊添加到項目中,接着在grunt.loadNpmTasks()
函數中像下面一樣添加PostCSS插件:
grunt.loadNpmTasks('grunt-postcss');
grunt.loadNpmTasks('grunt-contrib-less');
接下來設置LESS處理器的新任務:
grunt.initConfig({
在現有的postcss
任務中添加下面的代碼:
less: { production: { files: { 'src/style.css': 'src/style.less' } } },
現在注冊運行LESS和PostCSS的任務。在grunt.loadNpmTasks()
函數中添加下面的代碼:
grunt.registerTask('css', ['less', 'postcss']);
測試預處理器
測試預處理器,重新將src/
目錄中的style.css
命名為style.less
,並且在測試文件中添加LESS代碼:
@font-stack: Helvetica, sans-serif; @primary-color: #333; body { font: 100% @font-stack; color: @primary-color; }
在命令行中執行grunt css
命令。你可以看到dest/
目錄中新創建了一個style.css
文件,並且包含了編譯之后的代碼:
body { font: 100% Helvetica, sans-serif; color: #333333; }
配置PostCSS
現在將PostCSS插件添加到工作流中。更新gruntfile.js
中processors
數組:
processors: [ require('autoprefixer')(), require('cssnano')() ]
測試PostCSS
將測試PostCSS的代碼添加到style.less
文件中,並且再次運行grunt css
。在dest/style.css
文件中可以看到PostCSS編譯后的代碼:
body{font:100% Helvetica,sans-serif;color:#333}.css_nano,.css_nano+p,[class*=css_nano]{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;margin:1rem 2.5rem 2rem 1.5rem;font-weight:400;padding:1.75rem;width:46.5rem}
接下來的教程
下一篇教程我們將介紹使用不同的PostCSS插件自動生成BEM/SUIT
的CSS類名。在這個過程中可以讓你能更好的跟蹤BEM/SUIT
開發過程,而且更有效率。
如果你對接下來的內容感興趣的話,歡迎持續關注這個系列教程的下一篇。
本文根據@Kezz Bracey的《Using PostCSS Together with Sass, Stylus, or LESS》所譯,整個譯文帶有我們自己的理解與思想,如果譯得不好或有不對之處還請同行朋友指點。如需轉載此譯文,需注明英文出處:http://webdesign.tutsplus.com/tutorials/using-postcss-together-with-sass-stylus-or-less--cms-24591。