淺談css預處理器,Sass、Less和Stylus
css 預處理器的由來。
相信前端開發人員對與CSS(Cascading Style Sheet-級聯樣式表)這種「面向命名語言」,一定非常熟悉。你可能在某個舍友熟睡的深夜,還在電腦面前被 css 繁重、冗雜的樣式,折磨的死去活來。
我們曾經面對 css 很多令人髮指的不友好特性,也因為 css 的低復用性而刀耕火種。
css 預處理器就是這樣被創造出來,彌補了直接寫 css 的一些缺憾:
- 語法不夠強大,比如無法嵌套書寫導致模塊化開發中需要書寫很多重複的選擇器;
- 沒有變數和合理的樣式復用機制,使得邏輯上相關的屬性值必須以字面量的形式重複輸出,導致難以維護。
本文將主要介紹 Sass、Less 和 Stylus 這三種 css 預處理器,將從各個角度比較它們的異同。
簡介
Sass:2007年誕生,最早也是最成熟的CSS預處理器,擁有ruby社區的支持和compass這一最強大的css框架,目前受LESS影響,已經進化到了全面兼容CSS的SCSS。sass 中文文檔Sass 參考手冊 Less:2009年出現,受SASS的影響較大,但又使用CSS的語法,讓大部分開發者和設計師更容易上手,在ruby社區之外支持者遠超過SASS,其缺點是比起SASS來,可編程功能不夠,不過優點是簡單和兼容CSS,反過來也影響了SASS演變到了SCSS的時代,著名的Twitter Bootstrap就是採用LESS做底層語言的。Less 中文文檔 Stylus:2010年產生,來自Node.js社區,主要用來給Node項目進行CSS預處理支持,在此社區之內有一定支持者,在廣泛的意義上人氣還完全不如SASS和LESS。Stylus 中文文檔
Sass
Sass有兩種語法,分別以「 *.sass 」和「 *.scss 」為擴展名。這裡你可以查看Sass 和 Scss 的異同。Sass 兼容 css ,你可以在 sass 文件里寫 css,也可以嚴格按照 sass 的縮進方式省去「大括弧」和「分號」,最終它們都會被編譯成標準 css,比如:
/*style.sass*/nh1n color: #666n background-color: #666tn
Less
Less 受 Sass 的影響非常大,以「 *.less 」為擴展名,是 sass 之後的又一款優秀的 css 預處理器。其特點包括:
- 變數:就像寫其他語言一樣,免於多處修改。
- 混合:class 之間的輕鬆引入和繼承。
- 嵌套:選擇器之間的嵌套使你的 less 非常簡潔。
- 函數&運算:就像 js 一樣,對 less 變數的操控更靈活。
比如這樣的 Less(來自bootcss/less)
@base: #f938ab;nn.box-shadow(@style, @c) when (iscolor(@c)) {n box-shadow: @style @c;n -webkit-box-shadow: @style @c;n -moz-box-shadow: @style @c;n}n.box-shadow(@style, @alpha: 50%) when (isnumber(@alpha)) {n .box-shadow(@style, rgba(0, 0, 0, @alpha));n}n.box { n color: saturate(@base, 5%);n border-color: lighten(@base, 30%);n div { .box-shadow(0 0 5px, 30%) }n}n
Stylus
相比於 sass 的激進和 less 的常規,Stylus 是一個高效、動態以及豐富的 CSS 預處理器。它同時支持縮進的和通俗的兩種風格的 CSS 語法風格。
Stylus 擴展名為「 *.styl 」,跟另外兩款 css 預處理器相比略顯年輕,社區以及推廣程度也不及 sass 和 less,但它的一些優秀特性同樣令人著迷。
Nib是 Stylus 的應用的類庫。給你的「 *.styl 」添加 Nib 的最快方式是克隆 Nib 的 Git 版本庫並引入,因為有了 Nib,Stylus 的高效性才更為突出。
除了包含 Less 的一些優點,Stylus 在容錯性上的突出特性也十分吸引我,你可以在一個 Stylus 文件里這樣寫,且它們都會被編譯成標準 css:
/*style.styl*/n/*類似於CSS標準語法*/nh1 {n color: #963;n background-color:#333;n}n/*省略大括弧({})*/nh1 n color: #963;n background-color: #333;n/*省略大括弧({})和分號(;)*/nh1n color:#963n background-color:#333n
下面從特性上比較三者異同:
1.變數:
- Sass聲明變數必須是『$』開頭,後面緊跟變數名和變數值,而且變數名和變數值需要使用冒號:分隔開。
- Less 聲明變數用『@』開頭,其餘等同 Sass。
- Stylus 中聲明變數沒有任何限定,結尾的分號可有可無,但變數名和變數值之間必須要有『等號』。但需要注意的是,如果用「@」符號來聲明變數,Stylus會進行編譯,但不會賦值給變數。就是說,Stylus 不要使用『@』聲明變數。Stylus 調用變數的方法和Less、Sass完全相同。
2.作用域:
css 預編譯器把變數賦予作用域,也就是存在生命周期。就像 js 一樣,它會先從局部作用域查找變數,依次向上級作用域查找。
- Sass:三者最差,不存在全局變數的概念。也就是說在 Sass 中定義了相同名字的變數時你就要小心蛋疼了。
- Less:我認為跟 JS 一樣,逐級查找,向上冒泡。
- Stylus:完全等同 Less。Stylus 和 Sass 則更傾向於指令式。
3.嵌套:
十分真誠的說,三種 css 預編譯器的「選擇器嵌套」在使用上來說沒有任何區別(也可能是我沒發現)。Sass 除了常規的採用『&』替代父級選擇器之外,還提供了「奇葩的屬性嵌套」:
/*style.sass*/n.footer {n font: {n family: 微軟雅黑;n size: 5rem;n weight: bolder;n }n}n
除了少打幾個字,感覺沒啥用啊。
4.繼承:
css 屬性的繼承是一個非常重要的特性,好消息是三種預編譯器都對此做出了改善。
- Sass和Stylus的繼承非常像,能把一個選擇器的所有樣式繼承到另一個選擇器上。使用『@extend』開始,後面接被繼承的選擇器。
.shit {n margin: 10px 5px;n padding: 2px;n}np {n @extend .shit;/*繼承.block*/n border: 1px solid #aaa;n}nul,li {n @extend .shit; /*繼承.block*/n color: #aaa;n}n
將被編譯成標準 css:
.shit,p,ul,ol {n margin: 10px 5px;n padding:2px;n}np {n border: 1px solid #aaan}nul,li {n color:#aaa;n}n
- Less 繼承:與前兩者繼承方式有所區別,它不是在選擇器上繼承,而是將Mixins中的樣式嵌套到每個選擇器裡面。然而這樣會帶來一個明顯的缺點:每個選擇器中會出現重複的樣式。
5.導入@Import:
CSS中,不建議用@import導入css,因為會增加http請求。但 CSS 預處理器中的導入和CSS的有hhe很大區別,它是將不同 css 是在語義上導入,最終編譯結果會生成一個CSS文件。
值得注意的是,如果不同文件相互引入的時候,出現相同變數名時可能會引起錯誤。所以我的建議是單獨有一個 var.sass/less/styl 文件來記錄所有你定義的變數。
Less 為@Import 擴展了語法,而 Sass 和 Stylus 並沒有。具體擴展的 import 語法請見:Less 的 Import 擴展
總結
個人認為:
- Sass和Less語法嚴謹、Stylus相對自由。因為Less長得更像 css,所以它可能學習起來更容易。
- Sass 和 Compass、Stylus 和 Nib 都是好基友。
- Sass 和 Stylus 都具有類語言的邏輯方式處理:條件、循環等,而 Less 需要通過When等關鍵詞模擬這些功能,這方面 Less 比不上 Sass 和 Stylus。
- Less 在豐富性以及特色上都不及 Sass 和 Stylus,若不是因為 Bootstrap 引入了 Less,可能它不會像現在這樣被廣泛應用(個人愚見)。
- 身邊有幾個朋友在 css 預編譯器的選擇上猶豫不決,其實我認為選擇什麼無所謂,關鍵在於你的熟練程度以及團隊合作方面的有利性。
- 當然,在大致學習、使用和研究了這三種 css 預編譯器之後,我想我會選擇 Stylus,它的語法自由度很高,而且寫出來的代碼非常簡潔,這點十分吸引我。
轉載請聯繫作者:Jeason-趙吉彤
歡迎大家關注我的專欄:代碼小白的日常 - 知乎專欄歡迎在我的 Github 上提 issue:jeasonstudio (趙吉彤) · GitHub
推薦閱讀:
※CPU會被GPU替代嗎?SIMD和SIMT誰更好?
※優雅地記錄Python程序日誌2:模塊組件化日誌記錄器
※Mac上安裝xampp,無法獲取到htdocs目錄下的某些項目文件夾。
※成為碼魔的三條路
※C、C++語言學習資料