淺談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++語言學習資料

    TAG:前端开发 | CSS | 编程 |