原文連接:http://www.smashingmagazine.com/2015/12/introduction-to-postcss/javascript
轉自:http://www.zcfy.cc/article/81css
CSS的發展與全部語言的發展同樣,都有一個迭代的過程。伴隨着每個主要版本的發佈,咱們均可以得到新的特性和語法幫忙咱們更好的完成樣式。CSS3 介紹了不少新的特性,可讓咱們設計交互,以前咱們都是經過javascript來實現交互。每一天都會有新工具出現,讓咱們能夠更靈活地表達樣式。html
PostCSS就是最近纔出現的這麼一個工具PostCSS。PostCSS的目標是經過自定義插件和工具這樣的生態系統來改造CSS。與Sass和Less這些預編譯器相同的原則,PostCSS把擴展的語法和特性轉換成現代的瀏覽器友好的CSS。前端
如何實現?JavaScript。java
JavaScript轉換咱們的樣式比其餘處理器快。使用Gulp或Grunt的task-runner工具,咱們能夠經過構建過程轉換樣式,就像Sass和Less的編譯。像React和AngularJS這樣的庫和框架,容許咱們能夠在JavaScript中直接寫CSS,爲咱們的樣式打開了一扇使用JavaScript轉換的大門。react
PostCSS做爲使用JavaScript處理CSS的方法被推出,它的開發者是Andrey Sitnik, Autoperfixer的做者。PostCSS自己只是一個API,當使用其龐大的插件生態系統時,能夠爲咱們提供強大的處理能力。生成的Source maps能夠方便咱們的調試,抽象語法樹(AST)的存在能夠幫忙咱們理解代碼是如何被轉換的。git
因爲PostCSS使用Node.js框架,不管語言仍是工具能夠按需修改和定製。其餘工具如Sass和LESS就會由於系統能力的限制,只可使用編譯器可用的方法。github
因爲其使用的API,PostCSS容許咱們爲可能須要的任何功能,建立自定義的插件和工具。模塊化平臺的設計使得工具中立,使得咱們只須要關注項目須要的功能。PostCSS對語言格式不關心,接受不一樣預處理器的語法風格,像Sass和LESS,若是有必要的話。web
大多數開發人員不多從頭開始一個項目。不少都是以Sass模板開始,在指定項目中使用Sass模板提供的variables,mixins,functions。咱們爲functions,mixins,表格系統,通用工具提代獨立的樣式表,從而使開發更容易。到了最後,咱們最終會有10個或更多個樣式文件用來保證開發的條理性。npm
維護Sass或Less片段的庫是一個艱鉅的任務,會留下一下臃腫的項目。不少項目中沒有用到mixins和funcitons,只是作爲"以防萬一"的代碼包含進來。PostCSS很容易安裝,即插即用的模塊,使有獨特需求的項目開發過程更靈活。
PostCSS把咱們產品中的樣式表中用來建立funtions,utities和mixins的代碼移出來包裝成插件。如今對於每一個項目,咱們能夠經過構建工具中包含對應插件就可使用這些工具。
PostCSS FontPath插件就能夠見證這種方式的優點。在使用Sass時,咱們能夠在文件中包含進一個mixin來自定義網頁字體,所以咱們建立了一個@font-face的標籤。
@mixin importfont($font-family,$font-filename,$font-weight:normal,$font-style:normal,$font-stretch:normal){
@font-face{
font-family:'#{$font-family}';
src:url('#{font-filename}.eot');
src:url('#{font-filename}.woff') format('woff'),
url('#{$font-filename}.ttf') format('truetype');
font-weight:$font-weight;
font-style:$font-style;
font-stretch:$font-stretch;
}
}
@include importfont('mission script','fonts/mission-script-webfont',300);
在咱們的項目中使用PostCSS FontPath 插件,咱們就再也不須要像上面那樣包含Sass mixins了。在咱們的CSS中寫入下面的代碼,PostCSS會經過Grunt或Gulp把它轉換成咱們須要的。
@font-face{
font-family:'My Font';
font-path:'/path/to/font/file';
font-weight:normal;
font-style:normal;
}
在寫這篇文章時,PostCSS已經有超過100個社區插件,容許諸如將來的CSS語法,快捷鍵,工具和語言的擴展。PostCSS除了是一個'酷'的工具,它的用戶羣裏也有WordPress,谷歌和推特團隊這些重量級的用戶。
由於PostCSS是用JavaScript編寫的,咱們能夠在項目中使用像Gulp和Grunt這樣的Task runner來轉換CSS。下面的教程演示如何把PostCSS使用Gulp或Grunt合併到你的工做流。使用這兩種工具不是相當重要的,這只是我的喜愛或哪個更合適項目的問題。
注意:Gulp和Grunt完整版的工具放在GitHub可用 。你能夠隨時使用它作爲初始模板,而且能夠根據須要擴展它。
若是你對Gulp不熟悉,我推薦你閱讀Callum Macrae寫的"基於Gulp構建"作個初步瞭解,並把這個工具跑起來。
在終端執行npm i gulp-postcss -D
命令,在你的項目中安裝PostCSS模塊。
在項目下的Gulpfile.js
中請求咱們安裝的PostCSS模塊,而後在任務中使用它。在這裏,必定要更新開發文件的路徑和輸出轉換文件的目錄。
var postcss = require('gulp-postcss');
gulp.task('styles',function(){
return gulp.src('path/to/dev/style.css')
.pipe(postcss([]))
.pipe(gulp.dest('path/to/prod'))
});
在命令行輸入gulp styles
執行該任務。
注意:若是你對Grunt不熟悉,我推薦你經過閱讀Mike Cunsolo寫的"Grunt入門和實踐"來熟悉Grunt的使用。
在終端執行npm i grunt-postcss -D
命令,在你的項目中安裝PostCSS模塊。
一旦在系統裏安裝了該插件,你就能夠像下面這樣,使用它在Gruntfile裏建立一個任務了。必定記得更新cwd
和dest
的值來反映你的應用程序結構。
module.exports = function(grunt){
grunt.initConfig({
pkg:grunt.file.readJSON('package.json'),
styles:{
options:{
processors:[]
},
dist:{
files:[{
expand:true,
cwd:'dev/',
src:['**/*.css'],
dest:'prod/'
}]
}
}
});
// 加載post-css
grunt.loadNpmTasks("grunt-postcss");
};
在命令行輸入grunt styles
執行該任務。
使用PostCSS本身並不徹底是強大的,它的強大依賴於插件。你可能已經注意到在上面Gulp和Grunt的實現中,任務聲明中有空的數組。在這些數組中咱們能夠引入社區開發的PostCSS插件。
覈準的PostCSS插件列表能夠在PostCSS GitHub頁 查看,這些插件像全部的NPM包同樣,能夠經過命令行安裝。許多插件只能作爲PostCSS的擴展,對於你使用的構建工具是不可知的。好比,咱們將要安裝的PostCSS Focus 插件,它將爲每個hover狀態添加:focus
。
下面例子中使用的全部插件,咱們須要使用命令行和NPM在咱們的項目中安裝這些包文件。
npm i postcss-focus -D
插件能夠直接傳遞到方法;然而,爲了代碼的整潔,咱們能夠構造一個數組做爲參數將其傳遞給方法。在這個數組裏,咱們包含必要的require
語句,該語句返回插件,接着當即調用返回的插件。若是你想深刻了解這個概念,推薦閱讀Ryan Christiani寫的Functions as First-Class Citizens in JavaScript這篇文章。
require('postcss-focus')()
Grunt使用新建立的processorArray
後的代碼,以下:
var processorArray = [
require('postcss-plugin')()
];
// Snipped for brevity
styles:{
options:{
processors:processorArray
},
dist:{
src:'path/to/dev/style.css',
dest:'path/to/prod/style.css'
}
}
Gulp修改後的代碼以下:
var processorArray = [
require('postcss-plugin')()
];
gulp.task('styles',function(){
gulp.src('path/to/dev/style.css')
.pipe(postcss(processorArray))
.pipe(gulp.dest('path/to/prod'))
});
一旦咱們安裝一個插件和構建工具準備編譯代碼,咱們就可使用PostCSS和插件的功能。首先咱們要作的是在開發目錄下新建一個.css
擴展的文件。
"等等!一個CSS文件?"沒錯,一個CSS文件。由於使用PostCSS轉換咱們的CSS,咱們不須要特定的語法,只須要使用傳統的CSS就能夠。若是你熟悉預處理器,離開了.sass
,.scss
,.styl
或.less
文件迴歸到.css
,你會以爲不天然。可是,事實上,它帶來的不是轉換而是轉變。
咱們能夠分別執行grunt styles
和gulp styles
使Task runner運行,利用咱們新安裝的PostCSS插件來處理咱們的樣式。咱們的開發樣式文件將經過PostCSS插件被處理,而後輸出到咱們指定的生產目錄。
如下是一些值得注意的插件,包括這些插件的安裝和使用說明,在你開始使用PostCSS時會有一些幫助。
編寫兼容衆多瀏覽器和設備的樣式是一種痛苦,須要添加供應商前綴保持最新的屬性和值更是一種挑戰。所幸,AutoPrefixer 能夠找出什麼時候何地須要提供前綴。該插件可讓咱們在樣式中使用新的特性和屬性,爲屬性和值添加前綴由它來完成。
這裏是如何經過命令行安裝這個插件:
npm i autoprefixer -D
當咱們在數組中添加一個插件時,咱們須要提供一個對象,該對象提供項目支持的瀏覽器範圍的數組。能夠提供的選項列表能夠在Browserslist Github Account中查看。
咱們在處理器中添加一個Autoprefixer插件
var processorsArray = [
// snipped for brevity
require('autoprefixer')({browsers:['last 2 versions','ie 6-8','Firefox > 20']})
]
根據設定的目標不一樣,樣式表中相應的CSS屬性和值上會自動加上適當的前綴。
這是開發的CSS:
.item{
display:flex;
flex-flow:row wrap;
}
這裏是轉換後的輸出:
.item{
display:-webkit-flex;
display:-ms-flexbox;
display:-webkit-box;
display:flex;
-webkit-flex-flow:row wrap;
-ms-flex-flow:row wrap;
flex-flow:row wrap;
}
CSS4不久將要來到咱們身邊,CSS4將帶來一些新的特性,如本地變量,自定義選擇器 和新的僞類連接 。在寫這篇文章時,這些新特性在全部瀏覽器都不支持,可是它們將在現代瀏覽器中實現規範獲得了批准。
CSSNext 能夠把任意的CSS4特徵或屬性轉換成瀏覽器能夠解析的CSS3屬性。這個工具能夠單獨使用,也能夠作爲PostCSS的插件使用。咱們接着把它也添加到processorsArray
,processorsArray
裏已經包含了其餘咱們須要的PostCSS插件。
經過命令行安裝CSSNext插件,以下:
npm i cssnext -D
(譯者注:cssnext官網正式改名爲postcss-cssnext,安裝時請使用npm i postcss-cssnext
,估計是避免與CSSNEXT混淆)
而後將它添加到你的處理器中:
var processorsArray = [
// snipped for brevity
require('cssnext')()
]
如今,在你的生產代碼中能夠寫CSS4的特性,PostCSS會經過任務管理器轉換這些語法,從而被今天的瀏覽器支持。再用開發文件中的CSS替換這些轉換後的代碼便可。
這裏是開發的CSS:
// 自定義變量
:root{
--linkColour:purple;
}
a{
color:var(--linkColour);
}
// 自定義媒體查詢範圍
@custom-media --only-medium-screen (width>=500px) and (width/
@import "partials/_base.css";
/* 混入(Mixins) */
@define-mixin square $dimension{
width:$dimension;
height:$dimension;
}
/* 嵌套,變量和混入 */
.button{
@mixin square 200px;
background:$green;
&:hover{
background:$blue;
}
}
這裏是轉化後的輸出:
.square{
background:#0000ff;
border-radius:10px;
}
.button{
width:200px;
height:200px;
background:#00ff00;
}
.button:hover{
background:#0000ff;
}
若是你想探索CSSNext更多的功能,能夠訪問playground 這個網站,在這個網站上你能夠嘗試更多CSSNext支持的CSS4特性。
若是Sass是你的首選預處理語言,不用擔憂:你能夠在PostCSS中使用Sass的語法和Sass的工具。傳統的CSS不支持變量,嵌套和引用,使用插件好比PreCSS 就可讓咱們使用這些特性,這樣咱們就能夠在傳統的樣式文件中使用Sass的語法。
若是經過命令行將插件添加到構建裏,參考上面的演示將該包添加到processorsArray數組裏,這樣咱們就能夠當即使用Sass語法了。若是咱們從Sass切換到了PostCSS,你須要把文件的擴展改爲.css
,而且在你的Task runner中當即執行。
經過命令行安裝PreCSS,以下:
npm i precss -D
把這個插件添加到你的處理器中:
var processorsArray = [
// snipped for brevity
require('precss')()
];
這裏是開發的CSS:
/* 變量 */
$blue:#0000ff;
$green:#00ff00;
$radius:10px;
.square{
background:$blue;
border-radius:$radius;
}
/* 引用 */
@import "partials/_base.css";
/* 混入(Mixins) */
@define-mixin square $dimension{
width:$dimension;
height:$dimension;
}
/* 嵌套,變量和混入 */
.button{
@mixin square 200px;
background:$green;
&:hover{
background:$blue;
}
}
這裏是轉化後的輸出:
.square{
background:#0000ff;
border-radius:10px;
}
.button{
width:200px;
height:200px;
background:#00ff00;
}
.button:hover{
background:#0000ff;
}
PostCSS的能力在於社區插件,插件能夠幫忙咱們更加有效的編寫代碼。這些插件給咱們提供了編寫代碼更快捷的方式,或者至少可使用更容易的方法來實現創造性的樣式。藉助PostCSS API,這些插件容許咱們在項目中能夠自定義屬性,選擇器和值,便得咱們能夠更有效的編寫樣式,儘可能少的使用搜索。
數量查詢功能很是強大。他們容許咱們在CSS中計算元素數量 ,從而基於兄弟元素的數量應用樣式。在今天,你能夠在CSS中使用數量查詢,由於數量查詢依賴一些先進的CSS選擇器,因此在寫這些選擇器時有點棘手。在線工具QQ的存在能夠幫忙咱們完成這樣的查詢,咱們也能夠在樣式中直接使用PostCSS自定義選擇器。
像其餘插件的安裝同樣,使用命令行安裝Quantity Queries插件,以下:
npm i postcss-quantity-queries -D
而且在你的處理器中添加這個插件:
var processors = [
// Snipped for brevity
require('postcss-quantity-queries')()
];
一旦這個插件安裝好,你就能夠只經過這個插件自定義選擇器和變量,基於匹配的元素應用樣式了。
這裏是開發的CSS:
// "至少"數量的兄弟元素應用樣式
.container > .item:at-least(5){
background:blue;
}
// "最多"數量的兄弟元素應用樣式
.item > a:at-most(10){
color:green;
}
// "範圍"數量的兄弟元素應用樣式
.gallery > img:between(4,7){
width:25%;
}
// "精確提供項"的兄弟元素應用樣式
.profiles:exactly(4){
flex:1 0 50%;
}
這裏是轉化後的輸出:
.container > .item:nth-last-child(n+5),
.container > .item:nth-last-child(n+5) ~ .item{
background:blue;
}
.item > a:nth-last-child(-n+10):first-child,
.item > a:nth-last-child(-n+10):first-child ~ a{
color:green;
}
.gallery > img:nth-last-child(n+4):nth-last-child(-n+7):first-child,
.gallery > img:nth-last-child(n+4):nth-last-child(-n+7):first-child ~ img{
width:25%;
}
.profiles:nth-last-child(4):first-child,
.profiles:nth-last-child(4):first-child ~.profiles{
flex:1 0 50%;
}
咱們在寫樣式時,偶爾會遇到一些屬性的語法讓你說,"應該能短一些"。所幸,Short插件能夠幫助咱們作到這一點:寫樣式更加有邏輯性。它讓咱們能夠爲position
和size
寫簡寫屬性,就像background
和font
屬性能夠凝聚成一個單一的聲明。
經過PostCSS API,簡寫聲明被轉換成瀏覽器易解析的樣式,容許一個簡潔開發樣式表和一個更有組織的生產樣式表。
使用命令行安裝Short:
npm i postcss-short -D
而且在你的處理器中添加這個插件:
var processors = [
require('postcss-short')()
];
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-spaceing
和font-family
。
這裏是開發的CSS:
p {
text:300 uppercase dimgrey center 1.6rem 1.7 .05em;
}
這裏是轉化後輸出的CSS:
p{
color:dimgrey;
font-weight:300;
text-align:center;
text-transform:uppercase;
font-size:25px;
font-size:1.6rem;
line-height:1.7;
letter-spaceing:.05em;
}
position
屬性容許top
,left
,'right',bottom
值包含在一個聲明中。值的順序 是順時針方向。語法中取值從1到4,若是有一個值你想排除,只需使用*星號替換便可。
這裏是開發的CSS:
section{
position: absolute 10px * *;
}
.topNav{
position: fixed 0 * * 0;
}
.modal{
position: fixed 40% 25%;
}
這裏是轉化後輸出的CSS:
section{
position:absolute;
top:10px;
}
.topNav{
position: fixed;
top:0;
left:0;
}
.modal{
position:fixed;
top:40%;
right:25%;
bottom:40%;
left:25%;
}
今天使用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差很少,都是提升樣式編寫效率的工具而已。
在接下來的幾年裏,咱們使用CSS的方式將會在許多不一樣的方面發生改變。每一個項目會有不一樣的需求,咱們將不得不調整咱們的開發方式。有了PostCSS這樣的模塊化生態系統,咱們就能夠根據項目需求選擇功能。
我鼓勵你去探索PostCSS的世界,而且探索它全部可用的插件。由於它是一個社區項目,只有人們去使用它並建立新的插件,這個生態系統纔會成長壯大。探索更多的插件,能夠訪問NPM的availabel packages,也能夠在PostCSS Playground中測試插件的功能。