英文原文:http://net.tutsplus.com/tutorials/html-css-techniques/sass-vs-less-vs-stylus-a-preprocessor-shootout 原文鏈接:http://www.w3cplus.com/css/sass-vs-less ...
英文原文:http://net.tutsplus.com/tutorials/html-css-techniques/sass-vs-less-vs-stylus-a-preprocessor-shootout
原文鏈接:http://www.w3cplus.com/css/sass-vs-less-vs-stylus-a-preprocessor-shootout.html
介紹
CSS預處理器是一種語言,用來編寫一些CSS的特性,而且無需考慮瀏覽器相容性的問題。他們通過編譯的代碼編寫成一般的CSS,不要在停留在石器時代了。CSS預處器有成千上萬的特性,在本文中我們將一一介紹。讓我們開始。
語法
在使用CSS預處器之前最重要的是對語法的理解,幸運的是,這三種CSS預處器的語法和CSS都差不多。
Sass和LESS
Sass和LESS都使用的是標準的CSS語法。這使用CSS預處器非常容易的將預處器代碼轉換成CSS代碼。預設Sass使用“.scss”擴展名,而LESS使用“.less”擴展名。Sass和LESS基本設置可以像下麵所示:
/* 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預處理器的功能,我並沒有提到的,希望在下麵的評論中與我們分享。