[譯]PostCSS介紹


PostCSS介紹

原文鏈接:http://www.smashingmagazine.com/2015/12/introduction-to-postcss/

轉自:http://www.zcfy.cc/article/81

CSS的發展與所有語言的發展一樣,都有一個迭代的過程。伴隨着每一個主要版本的發布,我們都可以獲得新的特性和語法幫忙我們更好的完成樣式。CSS3 介紹了很多新的特性,可以讓我們設計交互,之前我們都是通過javascript來實現交互。每一天都會有新工具出現,讓我們可以更靈活地表達樣式。

PostCSS就是最近才出現的這么一個工具PostCSS。PostCSS的目標是通過自定義插件和工具這樣的生態系統來改造CSS。與Sass和Less這些預編譯器相同的原則,PostCSS把擴展的語法和特性轉換成現代的瀏覽器友好的CSS。

如何實現?JavaScript。

JavaScript轉換我們的樣式比其他處理器快。使用Gulp或Grunt的task-runner工具,我們可以通過構建過程轉換樣式,就像Sass和Less的編譯。像React和AngularJS這樣的庫和框架,允許我們可以在JavaScript中直接寫CSS,為我們的樣式打開了一扇使用JavaScript轉換的大門。

PostCSS的歷史

PostCSS作為使用JavaScript處理CSS的方法被推出,它的開發者是Andrey Sitnik, Autoperfixer的作者。PostCSS本身只是一個API,當使用其龐大的插件生態系統時,可以為我們提供強大的處理能力。生成的Source maps可以方便我們的調試,抽象語法樹(AST)的存在可以幫忙我們理解代碼是如何被轉換的。

由於PostCSS使用Node.js框架,無論語言還是工具可以按需修改和定制。其他工具如Sass和LESS就會因為系統能力的限制,只可以使用編譯器可用的方法。

由於其使用的API,PostCSS允許我們為可能需要的任何功能,創建自定義的插件和工具。模塊化平台的設計使得工具中立,使得我們只需要關注項目需要的功能。PostCSS對語言格式不關心,接受不同預處理器的語法風格,像Sass和LESS,如果有必要的話。

模塊化的好處

大多數開發人員很少從頭開始一個項目。很多都是以Sass模板開始,在指定項目中使用Sass模板提供的variables,mixins,functions。我們為functions,mixins,表格系統,通用工具提代獨立的樣式表,從而使開發更容易。到了最后,我們最終會有10個或更多個樣式文件用來保證開發的條理性。

維護Sass或Less片斷的庫是一個艱巨的任務,會留下一下臃腫的項目。很多項目中沒有用到mixins和funcitons,只是做為"以防萬一"的代碼包含進來。PostCSS很容易安裝,即插即用的模塊,使有獨特需求的項目開發過程更靈活。

PostCSS把我們產品中的樣式表中用來創建funtions,utities和mixins的代碼移出來包裝成插件。現在對於每個項目,我們可以通過構建工具中包含對應插件就可以使用這些工具。

PostCSS FontPath插件就可以見證這種方式的優勢。在使用Sass時,我們可以在文件中包含進一個mixin來自定義網頁字體,因此我們創建了一個@font-face的標簽。

  1. @mixin importfont($font-family,$font-filename,$font-weight:normal,$font-style:normal,$font-stretch:normal){
  2. @font-face{
  3. font-family:'#{$font-family}';
  4. src:url('#{font-filename}.eot');
  5. src:url('#{font-filename}.woff') format('woff'),
  6. url('#{$font-filename}.ttf') format('truetype');
  7. font-weight:$font-weight;
  8. font-style:$font-style;
  9. font-stretch:$font-stretch;
  10. }
  11. }
  12. @include importfont('mission script','fonts/mission-script-webfont',300);

在我們的項目中使用PostCSS FontPath 插件,我們就不再需要像上面那樣包含Sass mixins了。在我們的CSS中寫入下面的代碼,PostCSS會通過Grunt或Gulp把它轉換成我們需要的。

  1. @font-face{
  2. font-family:'My Font';
  3. font-path:'/path/to/font/file';
  4. font-weight:normal;
  5. font-style:normal;
  6. }

在寫這篇文章時,PostCSS已經有超過100個社區插件,允許諸如未來的CSS語法,快捷鍵,工具和語言的擴展。PostCSS除了是一個'酷'的工具,它的用戶群里也有WordPress,谷歌和推特團隊這些重量級的用戶。

添加PostCSS到你的工作流

因為PostCSS是用JavaScript編寫的,我們可以在項目中使用像GulpGrunt這樣的Task runner來轉換CSS。下面的教程演示如何把PostCSS使用Gulp或Grunt合並到你的工作流。使用這兩種工具不是至關重要的,這只是個人喜好或哪一個更合適項目的問題。

注意:Gulp和Grunt完整版的工具放在GitHub可用 。你可以隨時使用它做為初始模板,並且可以根據需要擴展它。

使用GULP設置POSTCSS

如果你對Gulp不熟悉,我推薦你閱讀Callum Macrae寫的"基於Gulp構建"做個初步了解,並把這個工具跑起來。

在終端執行npm i gulp-postcss -D命令,在你的項目中安裝PostCSS模塊。

在項目下的Gulpfile.js中請求我們安裝的PostCSS模塊,然后在任務中使用它。在這里,一定要更新開發文件的路徑和輸出轉換文件的目錄。

  1. var postcss = require('gulp-postcss');
  2. gulp.task('styles',function(){
  3. return gulp.src('path/to/dev/style.css')
  4. .pipe(postcss([]))
  5. .pipe(gulp.dest('path/to/prod'))
  6. });

在命令行輸入gulp styles執行該任務。

使用GRUNT設置POSTCSS

注意:如果你對Grunt不熟悉,我推薦你通過閱讀Mike Cunsolo寫的"Grunt入門和實踐"來熟悉Grunt的使用。

在終端執行npm i grunt-postcss -D命令,在你的項目中安裝PostCSS模塊。

一旦在系統里安裝了該插件,你就可以像下面這樣,使用它在Gruntfile里創建一個任務了。一定記得更新cwddest的值來反映你的應用程序結構。

  1. module.exports = function(grunt){
  2. grunt.initConfig({
  3. pkg:grunt.file.readJSON('package.json'),
  4. styles:{
  5. options:{
  6. processors:[]
  7. },
  8. dist:{
  9. files:[{
  10. expand:true,
  11. cwd:'dev/',
  12. src:['**/*.css'],
  13. dest:'prod/'
  14. }]
  15. }
  16. }
  17. });
  18. // 加載post-css
  19. grunt.loadNpmTasks("grunt-postcss");
  20. };

在命令行輸入grunt styles執行該任務。

安裝插件

使用PostCSS自己並不完全是強大的,它的強大依賴於插件。你可能已經注意到在上面Gulp和Grunt的實現中,任務聲明中有空的數組。在這些數組中我們可以引入社區開發的PostCSS插件。

核准的PostCSS插件列表可以在PostCSS GitHub頁 查看,這些插件像所有的NPM包一樣,可以通過命令行安裝。許多插件只能做為PostCSS的擴展,對於你使用的構建工具是不可知的。比如,我們將要安裝的PostCSS Focus 插件,它將為每一個hover狀態添加:focus

下面例子中使用的所有插件,我們需要使用命令行和NPM在我們的項目中安裝這些包文件。

POSTCSS插件安裝示例

npm i postcss-focus -D

插件可以直接傳遞到方法;然而,為了代碼的整潔,我們可以構造一個數組作為參數將其傳遞給方法。在這個數組里,我們包含必要的require語句,該語句返回插件,接着立即調用返回的插件。如果你想深入了解這個概念,推薦閱讀Ryan Christiani寫的Functions as First-Class Citizens in JavaScript這篇文章。

  1. require('postcss-focus')()

Grunt使用新創建的processorArray后的代碼,如下:

  1. var processorArray = [
  2. require('postcss-plugin')()
  3. ];
  4. // Snipped for brevity
  5. styles:{
  6. options:{
  7. processors:processorArray
  8. },
  9. dist:{
  10. src:'path/to/dev/style.css',
  11. dest:'path/to/prod/style.css'
  12. }
  13. }

Gulp修改后的代碼如下:

  1. var processorArray = [
  2. require('postcss-plugin')()
  3. ];
  4. gulp.task('styles',function(){
  5. gulp.src('path/to/dev/style.css')
  6. .pipe(postcss(processorArray))
  7. .pipe(gulp.dest('path/to/prod'))
  8. });

插件

一旦我們安裝一個插件和構建工具准備編譯代碼,我們就可以使用PostCSS和插件的功能。首先我們要做的是在開發目錄下新建一個.css擴展的文件。

"等等!一個CSS文件?"沒錯,一個CSS文件。因為使用PostCSS轉換我們的CSS,我們不需要特定的語法,只需要使用傳統的CSS就可以。如果你熟悉預處理器,離開了.sass,.scss,.styl.less文件回歸到.css,你會覺得不自然。但是,事實上,它帶來的不是轉換而是轉變。

我們可以分別執行grunt stylesgulp styles使Task runner運行,利用我們新安裝的PostCSS插件來處理我們的樣式。我們的開發樣式文件將通過PostCSS插件被處理,然后輸出到我們指定的生產目錄。

以下是一些值得注意的插件,包括這些插件的安裝和使用說明,在你開始使用PostCSS時會有一些幫助。

自動加前綴

編寫兼容眾多瀏覽器和設備的樣式是一種痛苦,需要添加供應商前綴保持最新的屬性和值更是一種挑戰。所幸,AutoPrefixer 可以找出何時何地需要提供前綴。該插件可以讓我們在樣式中使用新的特性和屬性,為屬性和值添加前綴由它來完成。

這里是如何通過命令行安裝這個插件:

  1. npm i autoprefixer -D

當我們在數組中添加一個插件時,我們需要提供一個對象,該對象提供項目支持的瀏覽器范圍的數組。可以提供的選項列表可以在Browserslist Github Account中查看。

我們在處理器中添加一個Autoprefixer插件

  1. var processorsArray = [
  2. // snipped for brevity
  3. require('autoprefixer')({browsers:['last 2 versions','ie 6-8','Firefox > 20']})
  4. ]

根據設定的目標不同,樣式表中相應的CSS屬性和值上會自動加上適當的前綴。

這是開發的CSS:

  1. .item{
  2. display:flex;
  3. flex-flow:row wrap;
  4. }

這里是轉換后的輸出:

  1. .item{
  2. display:-webkit-flex;
  3. display:-ms-flexbox;
  4. display:-webkit-box;
  5. display:flex;
  6. -webkit-flex-flow:row wrap;
  7. -ms-flex-flow:row wrap;
  8. flex-flow:row wrap;
  9. }

利用CSSNEXT使用未來語法

CSS4不久將要來到我們身邊,CSS4將帶來一些新的特性,如本地變量,自定義選擇器 和新的偽類鏈接 。在寫這篇文章時,這些新特性在所有瀏覽器都不支持,但是它們將在現代瀏覽器中實現規范得到了批准。

CSSNext 可以把任意的CSS4特征或屬性轉換成瀏覽器可以解析的CSS3屬性。這個工具可以單獨使用,也可以做為PostCSS的插件使用。我們接着把它也添加到processorsArrayprocessorsArray里已經包含了其他我們需要的PostCSS插件。

通過命令行安裝CSSNext插件,如下:

npm i cssnext -D

(譯者注:cssnext官網正式更名為postcss-cssnext,安裝時請使用npm i postcss-cssnext,估計是避免與CSSNEXT混淆)

然后將它添加到你的處理器中:

  1. var processorsArray = [
  2. // snipped for brevity
  3. require('cssnext')()
  4. ]

現在,在你的生產代碼中可以寫CSS4的特性,PostCSS會通過任務管理器轉換這些語法,從而被今天的瀏覽器支持。再用開發文件中的CSS替換這些轉換后的代碼即可。

這里是開發的CSS:

  1. // 自定義變量
  2. :root{
  3. --linkColour:purple;
  4. }
  5. a{
  6. color:var(--linkColour);
  7. }
  8. // 自定義媒體查詢范圍
  9. @custom-media --only-medium-screen (width>=500px) and (width/
  10. @import "partials/_base.css";
  11. /* 混入(Mixins) */
  12. @define-mixin square $dimension{
  13. width:$dimension;
  14. height:$dimension;
  15. }
  16. /* 嵌套,變量和混入 */
  17. .button{
  18. @mixin square 200px;
  19. background:$green;
  20. &:hover{
  21. background:$blue;
  22. }
  23. }

這里是轉化后的輸出:

  1. .square{
  2. background:#0000ff;
  3. border-radius:10px;
  4. }
  5. .button{
  6. width:200px;
  7. height:200px;
  8. background:#00ff00;
  9. }
  10. .button:hover{
  11. background:#0000ff;
  12. }

如果你想探索CSSNext更多的功能,可以訪問playground 這個網站,在這個網站上你可以嘗試更多CSSNext支持的CSS4特性。

SASS語法

如果Sass是你的首選預處理語言,不用擔心:你可以在PostCSS中使用Sass的語法和Sass的工具。傳統的CSS不支持變量,嵌套和引用,使用插件比如PreCSS 就可以讓我們使用這些特性,這樣我們就可以在傳統的樣式文件中使用Sass的語法。

如果通過命令行將插件添加到構建里,參考上面的演示將該包添加到processorsArray數組里,這樣我們就可以立即使用Sass語法了。如果我們從Sass切換到了PostCSS,你需要把文件的擴展改成.css,並且在你的Task runner中立即執行。

通過命令行安裝PreCSS,如下:

  1. npm i precss -D

把這個插件添加到你的處理器中:

  1. var processorsArray = [
  2. // snipped for brevity
  3. require('precss')()
  4. ];

這里是開發的CSS:

  1. /* 變量 */
  2. $blue:#0000ff;
  3. $green:#00ff00;
  4. $radius:10px;
  5. .square{
  6. background:$blue;
  7. border-radius:$radius;
  8. }
  9. /* 引用 */
  10. @import "partials/_base.css";
  11. /* 混入(Mixins) */
  12. @define-mixin square $dimension{
  13. width:$dimension;
  14. height:$dimension;
  15. }
  16. /* 嵌套,變量和混入 */
  17. .button{
  18. @mixin square 200px;
  19. background:$green;
  20. &:hover{
  21. background:$blue;
  22. }
  23. }

這里是轉化后的輸出:

  1. .square{
  2. background:#0000ff;
  3. border-radius:10px;
  4. }
  5. .button{
  6. width:200px;
  7. height:200px;
  8. background:#00ff00;
  9. }
  10. .button:hover{
  11. background:#0000ff;
  12. }

利用社區插件擴展CSS

PostCSS的能力在於社區插件,插件可以幫忙我們更加有效的編寫代碼。這些插件給我們提供了編寫代碼更快捷的方式,或者至少可以使用更容易的方法來實現創造性的樣式。借助PostCSS API,這些插件允許我們在項目中可以自定義屬性,選擇器和值,便得我們可以更有效的編寫樣式,盡量少的使用搜索。

QUANTITY QUERIES

數量查詢功能非常強大。他們允許我們在CSS中計算元素數量 ,從而基於兄弟元素的數量應用樣式。在今天,你可以在CSS中使用數量查詢,因為數量查詢依賴一些先進的CSS選擇器,所以在寫這些選擇器時有點棘手。在線工具QQ的存在可以幫忙我們完成這樣的查詢,我們也可以在樣式中直接使用PostCSS自定義選擇器。

像其他插件的安裝一樣,使用命令行安裝Quantity Queries插件,如下:

  1. npm i postcss-quantity-queries -D

並且在你的處理器中添加這個插件:

  1. var processors = [
  2. // Snipped for brevity
  3. require('postcss-quantity-queries')()
  4. ];

一旦這個插件安裝好,你就可以只通過這個插件自定義選擇器和變量,基於匹配的元素應用樣式了。

這里是開發的CSS:

  1. // "至少"數量的兄弟元素應用樣式
  2. .container > .item:at-least(5){
  3. background:blue;
  4. }
  5. // "最多"數量的兄弟元素應用樣式
  6. .item > a:at-most(10){
  7. color:green;
  8. }
  9. // "范圍"數量的兄弟元素應用樣式
  10. .gallery > img:between(4,7){
  11. width:25%;
  12. }
  13. // "精確提供項"的兄弟元素應用樣式
  14. .profiles:exactly(4){
  15. flex:1 0 50%;
  16. }

這里是轉化后的輸出:

  1. .container > .item:nth-last-child(n+5),
  2. .container > .item:nth-last-child(n+5) ~ .item{
  3. background:blue;
  4. }
  5. .item > a:nth-last-child(-n+10):first-child,
  6. .item > a:nth-last-child(-n+10):first-child ~ a{
  7. color:green;
  8. }
  9. .gallery > img:nth-last-child(n+4):nth-last-child(-n+7):first-child,
  10. .gallery > img:nth-last-child(n+4):nth-last-child(-n+7):first-child ~ img{
  11. width:25%;
  12. }
  13. .profiles:nth-last-child(4):first-child,
  14. .profiles:nth-last-child(4):first-child ~.profiles{
  15. flex:1 0 50%;
  16. }

利用SHORT擴展簡寫屬性

我們在寫樣式時,偶爾會遇到一些屬性的語法讓你說,"應該能短一些"。所幸,Short插件可以幫助我們做到這一點:寫樣式更加有邏輯性。它讓我們可以為positionsize寫簡寫屬性,就像backgroundfont屬性可以凝聚成一個單一的聲明。

通過PostCSS API,簡寫聲明被轉換成瀏覽器易解析的樣式,允許一個簡潔開發樣式表和一個更有組織的生產樣式表。

使用命令行安裝Short:

  1. npm i postcss-short -D

並且在你的處理器中添加這個插件:

  1. var processors = [
  2. require('postcss-short')()
  3. ];

text屬性包括這些輸入屬性:color,font-style,font-variant,font-weight,font-stretch,text-decoration,text-align,text-rendering,text-transform,white-space,font-size,line-height,letter-spacing,word-spaceingfont-family

這里是開發的CSS:

  1. p {
  2. text:300 uppercase dimgrey center 1.6rem 1.7 .05em;
  3. }

這里是轉化后輸出的CSS:

  1. p{
  2. color:dimgrey;
  3. font-weight:300;
  4. text-align:center;
  5. text-transform:uppercase;
  6. font-size:25px;
  7. font-size:1.6rem;
  8. line-height:1.7;
  9. letter-spaceing:.05em;
  10. }

position屬性允許top,left,'right',bottom值包含在一個聲明中。值的順序 是順時針方向。語法中取值從1到4,如果有一個值你想排除,只需使用*星號替換即可。

這里是開發的CSS:

  1. section{
  2. position: absolute 10px * *;
  3. }
  4. .topNav{
  5. position: fixed 0 * * 0;
  6. }
  7. .modal{
  8. position: fixed 40% 25%;
  9. }

這里是轉化后輸出的CSS:

  1. section{
  2. position:absolute;
  3. top:10px;
  4. }
  5. .topNav{
  6. position: fixed;
  7. top:0;
  8. left:0;
  9. }
  10. .modal{
  11. position:fixed;
  12. top:40%;
  13. right:25%;
  14. bottom:40%;
  15. left:25%;
  16. }

這對我們的行業意味着什么?

今天使用PostCSS完全有可能獲得實惠。就像編譯Sass和Less,你可以把PostCSS合並到你的工作流中,通過修改Task runner來處理PostCSS。合並的插件像PreCSS允許你將現有的Sass項目移植到PostCSS,而不需要做任何的語法轉化。

本文撰寫之時,關於在什么地方寫CSS最好的討論正在持續。伴隨着React 庫越來越普及,在組件自身內部寫樣式,使用JavaScript直接轉換CSS進行編譯,這種思路正蓄勢待發。雖然這仍然是個討論,但使用PostCSS轉換樣式確實是一種方法。

另一個在行業內掀起波瀾的項目是CSS模塊, 樣式作用范圍在本地文件,需要使用時直接引用該文件。這個概念在JavaScript圈已經非常流行。隨着前端語言之間的界線越來越模糊,比如React和JSX ,CSS和JavaScript結合的能量不容忽視。

PostCSS通過自定義語法和屬性以嶄新方式擴展CSS,它的復雜性也將會為試圖熟悉這個語言的初學者帶來新的挑戰。如果在項目中使用PostCSS的是一位年輕的開發者,請多多鼓勵他深入了解CSS本身,以及理解PostCSS其實與Sass差不多,都是提高樣式編寫效率的工具而已。

今天采用PostCSS

在接下來的幾年里,我們使用CSS的方式將會在許多不同的方面發生改變。每個項目會有不同的需求,我們將不得不調整我們的開發方式。有了PostCSS這樣的模塊化生態系統,我們就可以根據項目需求選擇功能。

我鼓勵你去探索PostCSS的世界,並且探索它所有可用的插件。因為它是一個社區項目,只有人們去使用它並創建新的插件,這個生態系統才會成長壯大。探索更多的插件,可以訪問NPM的availabel packages,也可以在PostCSS Playground中測試插件的功能。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM