英文原文:http://net.tutsplus.com/tutorials/html-css-techniques/sass-vs-less-vs-stylus-a-preprocessor-shootoutphp
中文譯文:http://www.w3cplus.com/css/sass-vs-less-vs-stylus-a-preprocessor-shootout.htmlcss
本文根據Johnathan Croom的《Sass vs. LESS vs. Stylus: Preprocessor Shootout》所譯,整個譯文帶有咱們本身的理解與思想,若是譯得很差或不對之處還請同行朋友指點。如需轉載此譯文,需註明英文出處:http://net.tutsplus.com/tutorials/html-css-techniques/sass-vs-less-vs-stylus-a-preprocessor-shootout/,以及做者相關信息html
——做者:Johnathan Croom前端
——譯者:大漠node
發揮CSS預處器的做用是一種頗有挑戰性的事情。CSS預處器有不一樣的語言,有不一樣的語法和功能。css3
在這篇文章中,咱們將介紹三種不一樣CSS預處器的蠻量、功能以及他們的好處——Sass、LESS和Stylusgit
介紹
CSS預處理器是一種語言,用來編寫一些CSS的特性,並且無需考慮瀏覽器兼容性的問題。他們經過編譯的代碼編寫成通常的CSS,不要在停留在石器時代了。CSS預處器有成千上萬的特性,在本文中咱們將一一介紹。讓咱們開始。github
語法
在使用CSS預處器以前最重要的是對語法的理解,幸運的是,這三種CSS預處器的語法和CSS都差很少。web
Sass和LESS
Sass和LESS都使用的是標準的CSS語法。這使用CSS預處器很是容易的將預處器代碼轉換成CSS代碼。默認Sass使用「.scss」擴展名,而LESS使用「.less」擴展名。Sass和LESS基本設置能夠像下面所示:sql
/* style.scss 或者 style.less */
h1 { color: #0982C1; }
正如你所看到的,在Sass和LESS樣式中,這樣的代碼是在簡單不過的了。
重要的一點是,Sass也同時支持老的語法,就是不使用花括號和分號,並且文件使用「.sass」擴展名,他的語法相似於:
/* style.sass */
h1
color: #0982c1
Stylus
Stylus的語法花樣多一些,它使用「.styl」的擴展名,Stylus也接受標準的CSS語法,可是他也接受不帶花括號和分號的語法,以下所示:
/* style.styl */
h1 { color: #0982C1; } /* 省略花括號 */ h1 color: #0982C1; /* 省略花括號和分號 */ h1 color #0982C1
你也能夠在同一個樣式單中使用不一樣的變量,例以下面的寫法也不會報錯:
h1 {
color #0982c1
}
h2
font-size: 1.2em
變量(Variables)
你能夠在CSS預處理器中聲明變量,並在整個樣式表中使用。CSS預處理器支持任何變量(例如:顏色、數值(不論是否包括單位)、文本)。而後你能夠在任意地方引用變量。
Sass
Sass聲明變量必須是「$」開頭,後面緊跟變量名和變量值,並且變量名和變量值須要使用冒號(:)隔開。就像CSS屬性同樣:
$mainColor: #0982c1; $siteWidth: 1024px; $borderStyle: dotted; body { color: $mainColor; border: 1px $borderStyle $mainColor; max-width: $siteWidth; }
LESS
LESS聲明變量和Sass聲明變量同樣,惟一區別是變量名前面使用是的「@」字符:
@mainColor: #0982c1; @siteWidth: 1024px; @borderStyle: dotted; body { color: @mainColor; border: 1px @borderStyle @mainColor; max-width: @siteWidth; }
Stylus
Stylus聲明變量沒有任何限定,你可使用"$"符號開始。結尾的分號(;)無關緊要,但變量名和變量值之間的等號(=)是須要的。有一點須要注意的是,若是咱們使用"@"符號開頭來聲明(0.22.4)變量,Stylus會進行編譯,但其對應的值並不會賦值給變量。換句話說,在Stylus中不要使用「@」符號開頭聲明變量。
mainColor = #0982c1
siteWidth = 1024px
$borderStyle = dotted body color mainColor border 1px $borderStyle mainColor max-width siteWidth
轉譯出來的CSS
上面的代碼都將轉譯成相同的CSS。你能夠想像一下,變量的做用有多大。咱們不須要爲了修改一個顏色而輸入許屢次,也不須要爲了修改一個寬度去到找尋找他.(咱們只須要修改定義好的變量,修改一次就足夠).下面是轉譯過來的CSS代碼:
body { color: #0982c1; border: 1px dotted #0982c1; max-width: 1024px; }
嵌套(Nesting)
若是咱們在CSS中多個元素有一個相同的父元素,那麼寫樣式會變得很乏味,咱們須要一遍一遍的在每一個元素前寫這個父元素.
section { margin: 10px; } section nav { height: 25px; } section nav a { color: #0982C1; } section nav a:hover { text-decoration: underline; }
相反,使用CSS預處理器,咱們能夠在父元素的花括號({})寫這些元素。同時可使用「&」符號來引用父選擇器。
Sass、LESS和Stylus
對於嵌套選擇器來講,三個CSS預處器都具備相同的語法:
section {
margin: 10px; nav { height: 25px; a { color: #0982C1; &:hover { text-decoration: underline; } } } }
轉譯出來的CSS
上面的預處器轉譯出來的CSS代碼。和咱們開始展現的CSS代碼是相同的。很是的方便吧!
section { margin: 10px; } section nav { height: 25px; } section nav a { color: #0982C1; } section nav a:hover { text-decoration: underline; }
混合(Mixins)
Mixins是預處器中的函數。平時你在寫樣式時確定有碰到過,某段CSS樣式常常要用到多個元素中,這樣你就須要重複的寫屢次。在CSS預處器中,你能夠爲這些公用的CSS樣式定義一個Mixin,而後在你CSS須要使用這些樣式的地方,直接調用你定義好的Mixin。這是一個很是有用的特性。Mixins是一個公認的選擇器,還能夠在Mixins中定義變量或者是默認參數。
Sass
/* Sass定義了一個名叫error的mixin,這個error設置了一個參數「$borderWidth」,在沒特別定義外,這個參數的值是默認值2px*/
@mixin error($borderWidth: 2px) { border: $borderWidth solid #F00; color: #F00; } .generic-error { padding: 20px; margin: 4px; @include error(); /* 調用error mixins */ } .login-error { left: 12px; position: absolute; top: 20px; @include error(5px); /* 調用error mixins,並將參數$borderWidth的值指定爲5px*/ }
LESS
/* LESS 定義了一個名叫error的mixin,這個error設置了一個參數「$borderWidth」,在沒特別定義外,這個參數的值是默認值2px */ .error(@borderWidth: 2px) { border: @borderWidth solid #F00; color: #F00; } .generic-error { padding: 20px; margin: 4px; .error(); /* 調用error mixins */ } .login-error { left: 12px; position: absolute; top: 20px; .error(5px); /* 調用error mixins,並將參數$borderWidth的值指定爲5px */ }
Stylus
/* Stylus 定義了一個名叫error的mixin,這個error設置了一個參數「$borderWidth」,在沒特別定義外,這個參數的值是默認值2px */
error(borderWidth= 2px) { border: borderWidth solid #F00; color: #F00; } .generic-error { padding: 20px; margin: 4px; error(); /* 調用error mixins */ } .login-error { left: 12px; position: absolute; top: 20px; error(5px); /* 調用error mixins,並將參數$borderWidth的值指定爲5px */ }
轉譯出來的CSS
上面三種CSS預處器轉譯出來的CSS代碼都是同樣的
.generic-error { padding: 20px; margin: 4px; border: 2px solid #f00; color: #f00; } .login-error { left: 12px; position: absolute; top: 20px; border: 5px solid #f00; color: #f00; }
Mixins在三種預處器中都有所不一樣:
- Sass:在Sass定義Mixins和LESS、Stylus有所不一樣,在聲明Mixins時須要使用「@mixin」,而後後面緊跟Mixins的名,他也能夠定義參數,同時能夠給這個參數設置一個默認值,但參數名是使用「$」符號開始,並且和參數值之間須要使用冒號(:)分開。另外在Sass中調用Mixins須要使用「@include」,而後在其後緊跟你要調用的Mixins名。
- LESS:LESS中聲明Mixins和CSS定義樣式很是相似,能夠將Mixins當作是一個選擇器,固然Mixins也能夠設置參數,並給參數設置默認值。不過設置參數的變量名是使用「@」開始,一樣參數和默認參數值之間須要使用冒號(:)分開。
- Stylus:Stylus和前二者也略有不一樣,他能夠不使用任何符號,就是直接定義Mixins名,而後在定義參數和默認值之間用等號(=)來鏈接。
上面只是Mixins在三個CSS預處器的簡單區別,詳細的還能夠進入他們的官網瞭解,或者對比一下上面的三段代碼。
—— 大漠
繼承(Inheritance)
在多個元素應用相同的樣式時,咱們在CSS一般都是這樣寫:
p,
ul, ol { /* 樣式寫在這 */ }
這樣作很是的好,但每每咱們須要給單獨元素添加另外的樣式,這個時候咱們就須要把其中選擇器單獨出來寫樣式,這樣一回來咱們維護樣式就至關的麻煩。爲了應對這個問題,CSS預處理器能夠從一個選擇繼承另外一個選擇器下的全部樣式。
Sass和Stylus
.block { margin: 10px 5px; padding: 2px; } p { @extend .block; /* 繼承.block全部樣式 */ border: 1px solid #EEE; } ul, ol { @extend .block; /* 繼承.block全部樣式 */ color: #333; text-transform: uppercase; }
上面的代碼轉譯成CSS
.block, p, ul, ol { margin: 10px 5px; padding: 2px; } p { border: 1px solid #EEE; } ul, ol { color: #333; text-transform: uppercase; }
LESS
LESS支持的繼承和Sass與Stylus不同,他不是在選擇器上繼承,而是將Mixins中的樣式嵌套到每一個選擇器裏面。這種方法的缺點就是在每一個選擇器中會有重複的樣式產生。
.block { margin: 10px 5px; padding: 2px; } p { .block; /* 繼承 '.block'中的樣式 */ border: 1px solid #EEE; } ul, ol { .block; /*繼承'.block' 中的樣式*/ color: #333; text-transform: uppercase; }
轉譯出來的CSS代碼
.block { margin: 10px 5px; padding: 2px; } p { margin: 10px 5px; padding: 2px; border: 1px solid #EEE; } ul, ol { margin: 10px 5px; padding: 2px; color: #333; text-transform: uppercase; }
正如所看到的,上面的代碼「.block」的樣式將會被插入到相應的你要繼承的選擇器中,但須要注意是的優先級的問題。
導入(import)
在CSS中,並不喜歡用@import來導入樣式,由於這樣的作法會增長HTTP的請求。可是在CSS預處理器中的導入(@import)規則和CSS的有所不一樣,它只是在語義上導入不一樣的文件,但最終結果是生成一個CSS文件。若是你是經過「@import 'file.css'」導入「file.css」樣式文件,那效果跟普通CSS導入樣式文件同樣。注意:導入文件中定義了變量、混合等信息也將會被引入到主樣式文件中,所以須要避免他們的相互衝突。
Sass、LESS和Stylus
/* file.{type} */
body { background: #EEE; }
@import "reset.css"; @import "file.{type}"; p { background: #0982C1; }
轉譯出來的CSS
@import "reset.css"; body { background: #EEE; } p { background: #0982C1; }
顏色函數
顏色函數是CSS預處裏器中內置的顏色函數功能,這些功能能夠對顏色值進行處理,例如顏色的變亮、變暗、漸變顏色等處理十分的方便。
Sass
lighten($color, 10%); /* 返回的顏色在$color基礎上變亮10% */ darken($color, 10%); /* 返回的顏色在$color基礎上變暗10% */ saturate($color, 10%); /* 返回的顏色在$color基礎上飽和度增長10% */ desaturate($color, 10%); /* 返回的顏色在$color基礎上飽和度減小10% */ grayscale($color); /* 返回$color的灰度色*/ complement($color); /* returns complement color of $color */ invert($color); /* 返回$color的反相色 */ mix($color1, $color2, 50%); /* mix $color1 with $color2 with a weight of 50% */
這只是Sass中顏色函數的一個簡單列表,更多詳細的介紹你能夠閱讀Sass文檔。
顏色函數何以運用到任何一個元素上都是一個有顏色的CSS屬性,下面是一個簡單的例子:
$color: #0982C1; h1 { background: $color; border: 3px solid darken($color, 50%);/*邊框顏色在$color的基礎上變暗50%*/ }
LESS
lighten(@color, 10%); /* 返回的顏色在@color基礎上變亮10% */ darken(@color, 10%); /* 返回的顏色在@color基礎上變暗10%*/ saturate(@color, 10%); /* 返回的顏色在@color基礎上飽和度增長10% */ desaturate(@color, 10%); /* 返回的顏色在@color基礎上飽和度下降10%*/ spin(@color, 10); /* 返回的顏色在@color基礎上色調增長10 */ spin(@color, -10); /* 返回的顏色在@color基礎上色調減小10 */ mix(@color1, @color2); /* 返回的顏色是@color1和@color2二者的混合色 */
LESS的完整顏色函數功能,請閱讀LESS 文檔
下面是LESS中如何使用一個顏色函數的簡單例子
@color: #0982C1; h1 { background: @color; border: 3px solid darken(@color, 50%); }
Stylus
lighten(color, 10%); /* 返回的顏色在'color'基礎上變亮10% */ darken(color, 10%); /* 返回的顏色在'color'基礎上變暗10% */ saturate(color, 10%); /* 返回的顏色在'color'基礎上飽和度增長10% */ desaturate(color, 10%); /* 返回的顏色在'color'基礎上飽和度下降10% */
有關於Stylus的顏色函數介紹,請閱讀Stylus文檔
下面是Stylus顏色函數的一個簡單實例
color = #0982C1
h1
background color
border 3px solid darken(color, 50%)
運算符(Operations)
咱們都向往在CSS作一些運算,可是沒法實現。可是在CSS預處器中對樣式作一些運算是一點問題都沒有了,例如:
Sass、LESS和Stylus
body { margin: (14px/2); top: 50px + 100px; right: 100px - 50px; left: 10 * 10; }
實際運用
咱們介紹了CSS預處理器各方面的特性,但咱們尚未實戰過。下面是CSS預處理器應用的一些例子。
屬性前綴
這是宣傳CSS預處理器的緣由之一,而且是一個很好的理由,這樣能夠節省大量的時間和汗水。建立一個minxin來處理瀏覽器的前綴問題是一個很簡單的,而且能節省大量的重複工做和痛苦的代碼編輯,咱們來看一個例子。
Sass
@mixin border-radius($values) { -webkit-border-radius: $values; -moz-border-radius: $values; border-radius: $values; } div { @include border-radius(10px); }
LESS
.border-radius(@values) {
-webkit-border-radius: @values; -moz-border-radius: @values; border-radius: @values; } div { .border-radius(10px); }
Stylus
border-radius(values) {
-webkit-border-radius: values; -moz-border-radius: values; border-radius: values; } div { border-radius(10px); }
轉譯出來的CSS
div { -webkit-border-radius: 10px; -moz-border-radius: 10px; border-radius: 10px; }
瀏覽器前綴的問題,主要是針對於CSS3屬性的運用,衆所周知,CSS3的屬性有並非全部瀏覽器都支持屬性的標準語法,所以在實際運用中時,不得不加上各瀏覽器的前綴來識別,這對於咱們前端人員來講是多麼苦逼的一件事情。雖然有prefix這樣的js腳本幫咱們解決,但對於怎麼說也須要額外添加一個腳本文件,這對於追求完美的同窗來講可能完法接受。
如今多了一種解決方案,就是使用CSS預處理器,如上面圓角的實現方法,這樣減輕了咱們不少工做量。若是你對這一部分實現方法感興趣,不仿花時間閱讀一下如下源碼:
- cssmixins:由 Matthew Wagerfield整理的CSS3屬性在三種預處理器中的Mixins的定義: LESS、 Sass (還有 SCSS)和 Stylus
- LESS-Prefixer
- Custom User @mixins
—— 大漠
3D文本
使用text-shadow的多重屬性製做 3D文本效果是一個很好的方法。惟一麻煩的問題就是修改文本陰影的顏色。若是咱們使用Mixin和顏色函數的話,實現3D文本效果就很是的輕鬆了,咱們來嘗試一下。
Sass
@mixin text3d($color) { color: $color; text-shadow: 1px 1px 0px darken($color, 5%), 2px 2px 0px darken($color, 10%), 3px 3px 0px darken($color, 15%), 4px 4px 0px darken($color, 20%), 4px 4px 2px #000; } h1 { font-size: 32pt; @include text3d(#0982c1); }
LESS
.text3d(@color) {
color: @color; text-shadow: 1px 1px 0px darken(@color, 5%), 2px 2px 0px darken(@color, 10%), 3px 3px 0px darken(@color, 15%), 4px 4px 0px darken(@color, 20%), 4px 4px 2px #000; } span { font-size: 32pt; .text3d(#0982c1); }
Stylus
text3d(color)
color: color
text-shadow: 1px 1px 0px darken(color, 5%), 2px 2px 0px darken(color, 10%), 3px 3px 0px darken(color, 15%), 4px 4px 0px darken(color, 20%), 4px 4px 2px #000 span font-size: 32pt text3d(#0982c1)
在Stylus中text-shadow的樣式寫在一行,是由於stylus中省略了花括號({})和分號(;)。
上面三種方法實現的效果都是同樣的:
列(Columns)
我第一次接觸CSS預處理器的時候,我就想着使用數字或者變量進行運算。使用數值和變量運算,能夠很方便的實現適應屏幕大小的佈局處理。只須要定義寬度的變量,咱們就能夠很方便的根據需求實現佈局。下面的例子就是這麼作的。
Sass
$siteWidth: 1024px; $gutterWidth: 20px; $sidebarWidth: 300px; body { margin: 0 auto; width: $siteWidth; } .content { float: left; width: $siteWidth - ($sidebarWidth+$gutterWidth); } .sidebar { float: left; margin-left: $gutterWidth; width: $sidebarWidth; }
LESS
@siteWidth: 1024px; @gutterWidth: 20px; @sidebarWidth: 300px; body { margin: 0 auto; width: @siteWidth; } .content { float: left; width: @siteWidth - (@sidebarWidth+@gutterWidth); } .sidebar { float: left; margin-left: @gutterWidth; width: @sidebarWidth; }
Stylus
siteWidth = 1024px;
gutterWidth = 20px; sidebarWidth = 300px; body { margin: 0 auto; width: siteWidth; } .content { float: left; width: siteWidth - (sidebarWidth+gutterWidth); } .sidebar { float: left; margin-left: gutterWidth; width: sidebarWidth; }
轉譯出來的CSS
body { margin: 0 auto; width: 1024px; } .content { float: left; width: 704px; } .sidebar { float: left; margin-left: 20px; width: 300px; }
明顯的怪癖
使用CSS預處器都是有些怪癖的,我須要去尋找一些這樣的人,若是你真的對這些感興趣,你能夠去搜索他們以及相關的文檔,由於在你使用CSS預處理器很是有幫助。
錯誤報告
若是你常用CSS,你會發現很難找到CSS中出錯的地方。也許你也會像我同樣,花一下午的時間,發了瘋的註解每行樣式代碼來尋找這個CSS錯誤。
CSS預處理器就輕鬆多了,他會給你報告錯誤。你能夠閱讀這篇文章,學習如何讓CSS預處理器報告錯誤。
註釋(Comments)
CSS預處理器支持「/* */」這樣的多行註釋方式(相似於CSS的註釋方式),也支持「//」單行註釋方式(相似於Javascript的註釋方式)。
須要注意,若是你要壓縮文件,你須要把全部註釋都刪除。
總結
三個預處理器咱們都覆蓋了(Sass、LESS和Stylus),都以他們獨特的特性完成了相同的效果。這樣讓開發人員更好的選擇適合本身的CSS預處理器,從而更好的維護本身的代碼,提升開發效率。
雖然不是開發的要求,但CSS預處理器能夠節省大量的時間,而且有一些很是有用的功能。
我鼓勵你們儘量的嘗試使用CSS預處理器,這樣就能夠有效的讓你選擇一個你最喜歡的和知道他爲何是受人青睞的。若是你尚未嘗試過使用CSS預處理器來寫你的CSS樣式,我強烈建議你嘗試一下。
若是你有最喜歡的CSS預處理器的功能,我並無提到的,但願在下面的評論中與咱們分享。
譯者手語:整個翻譯依照原文線路進行,並在翻譯過程略加了我的對技術的理解。若是翻譯有不對之處,還煩請同行朋友指點。謝謝!