CSS預處理器的出現大大的提高了前端開發的效率和逼格,它讓CSS可編程化。LESS和Sass/SCSS是兩種最為常見的預處理器,擁有大量的用戶基數,數目龐雜的第三方庫。然而,還有一種預處理器並未引起足夠的重視,Stylus。
現在,我們來說說為什么Stylus很棒,為什么使用它,為什么它將會變成你的首選預處理器。
LESS、Sass很棒
具體介紹Stylus如何工作之前,我們先說說LESS、Sass給CSS帶來了什么好處,然而卻為什么不選擇它們。
預處理器的基石
每種預處理器都包含了變量、混寫(mixins)、嵌套和擴展,以及不同的度量單位、邏輯運算符和函數。通過這些你可以抽象出許多關鍵不瘋,並重復使用,良好的邏輯和更少的代碼能讓你從書寫CSS中獲得前所未有的體驗。
然而,最終促使我選擇使用哪個預處理器原因就是它們之間細微的不同。
LESS:很棒
除了一些基本功能外,LESS外圍的社區環境以及社區成員提供的大量資源是它的最大優勢。想必沒有一個前端工程沒聽說過Twitter Bootstrap的框架,這或許也是導致大部分人用LESS的原因之一。
另外一個使LESS脫穎而出的原因就是LESS的第三方庫,LESShat,它提供了一系列針對CSS3效果的混寫規則,並且還擁有針對Photoshop的配套插件CSShat,能夠方便的識別PSD文件並生成LESS代碼。假如你的Photoshop文件很復雜,那么這兩個工具將會給你的工作流程提供強有力的支持。
還有一個重要因素或許是許多人發現它非常容易上手且易於使用。你可以僅用一個簡單的Javascript文件編譯它,也可以用IDE內置的編譯器,還可以用nodejs在任何機器上編譯它。
LESS:為什么不用
首先,我更傾向於寫自己的代碼而不是用第三方框架,並且我現在正在設計更簡單的Photoshop,同時盡可能在瀏覽器中動態的設計,這有利於實時查看效果。所以,對我來說,上述提到的優勢還不足以促使我去選擇使用它。
但是最重要的原因其實是,LESS在邏輯處理上與另外兩個預處理器相比真是大相徑庭。
LESS只提供了少量的邏輯處理特性,以至於我們不得不為實現某些邏輯而增加代碼的書寫,這進一步導致了開發變緩以及后期維護成本的增加。
雖然LESS提供了一些邏輯處理,但是相比Stylus和Sass/Scss而言實在是太有限了。接下來我就會告訴你有限在哪里。
Sass:非常棒
Sass同樣擁有活躍的社區,優質的資源。LESS有Twitter Bootstrap,Sass有Gumby和Foundation。LESS有LESShat,Sass有Compass和Bourbon。
但是相比LESS的邏輯處理能力而言,Sass簡直就是神。在邏輯處理上,LESS勉強只能稱得上為CSS增強寫法,而Sass完全像一個復雜的編程語言。
舉個例子,Sass能讓你寫出有效的條件檢查,這很有用,尤其是在混寫中。
@mixin border_and_bg( $border_on, $border_color, $bg_on, $bg_color ){
@if $border_on == true {
border: 1px solid $border_color;
} @else {
border: 0;
}
@if $bg_on == true {
background-color: $bg_color;
} @else {
background-color: transparent;
}
}
這段代碼檢測$border_on
是否為true
,為true
則輸出的border
顏色屬性值為$border_color
的值。如果為false
則設置border
屬性為0
。
同時它還檢測了$bg_on
是否為true
,為true
則輸出background-color
值為$bg_color
的值。為false
的話設置background-color
為transparent
。
這樣,根據輸入的值,我們就可以輸出四種不同的樣式。
然而,在LESS里面沒有if/else
判斷,所以上面的代碼就無法實現。你最多能用用所謂“Guarded Mixins”的方法,基於單條表達式的判斷,就像這樣:
.border_and_bg ( @border_on, @border_color, @bg_on, @bg_color ) when (@border_on = true) {
border: 1px solid @border_color;
}
由於沒有if/else
函數,也就對隨后檢查@bg_on
的值無能為力,也就不能在同一個混寫當中根據可變的值設置border
屬性。
如果要實現Sass中同樣的功能,你需要用LESS創建四條不同的混寫,就像這樣:
.border_and_bg ( @border_on, @border_color, @bg_on, @bg_color ) when (@border_on = true) and (@bg_on = true) {
border: 1px solid $border_color;
background-color: @bg_color;
}
.border_and_bg ( @border_on, @border_color, @bg_on, @bg_color ) when (@border_on = false) and (@bg_on = false) {
border: 0;
background-color: transparent;
}
.border_and_bg ( @border_on, @border_color, @bg_on, @bg_color ) when (@border_on = false) and (@bg_on = true) {
border: 0;
background-color: @bg_color;
}
.border_and_bg ( @border_on, @border_color, @bg_on, @bg_color ) when (@border_on = true) and (@bg_on = false) {
border: 1px solid @border_color;
background-color: transparent;
}
這僅僅只是檢查兩個值,當你的代碼越來越復雜,需檢查的值越來越多,這種寫法將會變得非常丑陋。處理好每條規則的順序並一眼分辨它們也變得難上加難。
對比Sass,有木有發現Sass的邏輯處理能讓你coding更加輕松,生活更加美好。Sass同樣提供了超贊的流程控制,像:@for
,@each
和@while
。
最后,在LESS中令人稱贊的函數,同樣能方便的Sass化。像這樣:
@function function-name($parameter) {
@return $dosomething + $parameter / $somethingelse;
}
這些邏輯函數讓你有可能創建自己的布局引擎,用em而不是px,顏色定義,以及把大量的定義用法從一個項目轉移到另一個項目,等等。
從我看到的聽到的,以及我個人的使用經驗來判斷,人們使用Sass而不是LESS的很大原因就在於,它擁有強大邏輯處理能力。
Sass:還是不用
顯然,LESS由於邏輯處理能力弱出局了,剩下Sass和Stylus,這兩個都有一系列強有力的特性支撐。
然而,我選擇Stylus,因為它既有Sass的強大,也具有LESS的易用性。
Stylues能做到所有Sass能做的,或許還更簡單,卻僅需要Javascript或者Node.js就能編譯。它有的使用方法非常順滑且簡單,並且它優美簡潔的語法也是我所鍾愛的。
對我來說,最大的痛點就是用Sass的話必須運行Ruby on Rails並且和gems打交道。我的任何項目中都不會用到Ruby,我要為了使用Sass冒着裝Ruby而導致的連接錯誤或者安裝錯誤並去解決它顯然有點得不償失。
我非常好奇那么非Rubyer,為了使用Sass而裝Ruby,真是有Geek精神。
假如我為了使用Sass而裝了Ruby,但我的工作依然需要Node.js,依然需要NPM安裝Glup,去監視文件的變化,壓縮靜態文件等等,依然需要安裝Bower來管理其它的包。
所以,如果一個編譯器像Stylus擁有強大的邏輯處理能力,並且與我平時所用的工具高度配合,這就是我選擇它的原因。
很多人發現使用Sass需要歷經復雜的Ruby安裝,從而導致了它們使用LESS。現在,Stylus在給你強大邏輯處理的同時,也給了你像LESS一樣簡單易用的安裝和編譯方式。
拋開Ruby復雜的安裝方式,僅就Sass強大的邏輯處理能力而言我可能也不會選擇它。Stylus特別的工作方式以及易讀的語法,相比LESS和Sass而言更加簡潔、靈活和順暢。
現在,我來告訴你為什么我選擇Stylus,並且你也會樂意去選擇。
用Stylus,現在
正如上所說,我選擇Stylus因為:
- 強大的邏輯處理能力
- 僅僅用Node.js / JavaScript (no Ruby)就能編譯
- 用Glup和Bower用到Nodejs,同樣Stylus也需要,不會增加而外的負擔
- 精簡、靈活的語法
- 方便易用的特性
那么我來介紹一點stylus的用法,來作證為什么選擇它。
很大一部分原因是因為我能用到平時項目中已經存在的工具處理Stylus,這些工具包括Stylus也能很好的與我所用的IDE協同。
Stylus語法
Stylus靈活的語法簡直讓我愛不釋手。
在LESS里面你必須按照傳統的方式書寫,{}
、:
、;
一個都不能少
Sass/SCSS給了你更多的選擇:
- SCSS編譯時提供給你更多的選擇,那么你就可以用常規的CSS寫法或者上面的寫法
- Sass里面可以完全拋棄
{}
、:
、;
,但是在這個文件里你也不能用常規的寫法了
Stylus相對而言就靈活很多,不必去設置任何編譯選項就能夠兼容這兩種寫法
- 只要你覺得舒服完全可以用
{}
、:
、;
- 當你不用的時候,只要使用適當的縮進就能達到效果
- 你也可以在同一個文件中混合使用這兩種方式
以下寫法都是合法的:
.my-style{
color: #000;
background-color: #fff;
border: 1px solid #ccc;
}
.my-style
color #000;
background-color #fff;
border 1px solid #ccc;
.my-style
color: #000
background-color: #fff
border: 1px solid #ccc
.my-style
color #000
background-color #fff
border 1px solid #ccc
只有Stylus能完全省略這些標點符號,盡情發揮你的想象力,想怎么寫就怎么寫吧。
當你省略掉這些標點符號后,你會驚奇的發現你的代碼會變得如此美妙。coding過程中,思維也變得無比的順暢,高亮提示也進一步提高代碼的可讀性。
同時,編譯器也是很人性滴。你可能出於某種理由要用常規的CSS寫法,來讓你的代碼更有組織性,盡管用吧。假如你不慎漏寫了一個分號,OK,沒問題,沒人會知道的。
Stylus變量,混寫,流程控制和函數
你已經看到在LESS和Sass中,變量、混寫、流程控制和函數是怎么樣的。在我看來,Stylus中的方式更加可看、可讀、可用。
在LESS里面,變量必須加上@
前綴。在Sass里面,必須加上$
前綴。在Stylus里面,不用加任何前綴。當然如果你喜歡你可以隨便用$
,但是@
是內置的保留字,所以不能用它。
同樣,混寫、流程控制和函數不用加任何前綴。
在LESS里,一個混寫必須按照像常規CSS的寫法去寫,並且LESS還沒有流程控制和自定義函數。
在Sass里,混寫必須以@mixin
開頭,並且使用的時候要用@include
,條件控制用@if
和@else
,函數要以@function
開頭,並在函數內部有一行@return
這些條條框框在stylus里面通通沒有,你可以很自然的寫這些,就像寫常規代碼一樣。早期我用Sass的時候這樣寫。
@mixin border_and_bg( $border_on, $border_color, $bg_on, $bg_color ){
@if $border_on == true {
border: 1px solid $border_color;
} @else {
border: 0;
}
@if $bg_on == true {
background-color: 1px solid $bg_color;
} @else {
background-color: transparent;
}
}
@function function-name($parameter) {
@return $dosomething + $parameter / $somethingelse;
}
使用的時候這樣:
.callem {
@include border_and_bg(true, #000, true, #fff);
font-size: function-name( 6 );
}
現在,在Stylus中這樣寫:
border_and_bg(border_on, border_color, bg_on, bg_color)
if border_on == true
border 1px solid border_color
else
border 0
if bg_on == true
background-color bg_color
else
background-color transparent
function-name(parameter)
dosomething + parameter /somethingelse
.callem
border_and_bg true #000 false #fff
font-size function-name(6)
有木有感覺看起來和讀起來都非常隨意,並且編譯后生成的代碼也保持着簡單易讀。
當調用border_and_bg
的時候,就像通常寫CSS的方法,不用大括號、分號、冒號。當然你也可以使用這些標點符號,這取決於你。
一些妙招
Stylus擁有成噸的超贊特性,需要你自己去發現。
http://learnboost.github.io/stylus/
在此,有兩個特性我必須要說說。
參數省略法
參數省略法允許你傳入未定義個數的參數。你可以先傳入一些確定的值參數,然后通過使用args...
和args.
獲取剩余的值。例如:
padded_box(box_sizing,args...)
box-sizing box_sizing
padding args
.abox
padded_box border-box 5px 10px
.anotherbox
padded_box content-box 20px
//編譯后
.abox {
box-sizing: border-box;
padding: 5px 10px;
}
.anotherbox {
box-sizing: content-box;
padding: 20px;
}
屬性引用
有時候你可能會在一段CSS代碼內重復使用某個值,如果專門為此設置一個變量,未免有點浪費資源。
我們有個大寶劍,通過它你可以方便的獲取已經聲明屬性的值。例如:
.onemorepaddedbox
padding-left 20px
padding-right 30px
width 1200px - @padding-left - @padding-right
//編譯后
.onemorepaddedbox {
padding-left: 20px;
padding-right: 30px;
width: 1150px;
}
你所需要做的只是用一個@
標記符就行,Stylus會自動在本樣式中尋找聲明,找不到的話就去向上查找父元素,找不到繼續向上,當查到根節點依然沒有的話就返回“null”
總結
總而言之使用Stylus,不會讓你后悔。