1. 程式人生 > >less和sass的區別

less和sass的區別

本文來自thoughtworks Jing Ren ,感謝Jing Ren的翻譯(中文版英文原文)。本人覺得很慚愧,有點竊取的行為,所以我必須再次宣告來自我們可愛的Jing Ren,並再次感謝她的不辭辛苦。

    如果你還在為web前段css設計,維護,開發困擾的,我覺得你可以嘗試下LESS或者Sass另類的動態css體系。

原文如下:

      自從我幾個月前開始使用LESS,我就成文了它的忠實粉絲。CSS對我來說從來都不是問題,但是LESS可以把一個主題中的顏色都設定成變數,來保持我的網 站在風格上統一,這個想法讓我很著迷。就好像我們有一個調色盤,上面有固定的幾個顏色,我們可以從中選擇,而不至於被顏色搞的發瘋,也不至於偏離軌道。

less-sass1.jpg

LESS和Sass,還可以做更多事情。它們有很多共同點,比如說:

混合(Mixins)- Classes for classes

帶引數的混合(Parametric mixins) - Classes to which you can pass parameters, like functions.

巢狀的規則 (Nested Rules)- class巢狀class,以減少重複程式碼

運算(Operations)- CSS中的計算

顏色方法(Color functions) - 用來修改顏色

名稱空間(Namespaces)- 為樣式分組,並且可以通過組名進行訪問

作用域(Scope)

- 對樣式進行暫時的修改

JavaScript求值(JavaScript evaluation) - 在CSS裡執行JavaScript表示式

LESS和Sass最大的區別是他們處理的方式。LESS是一個JavaScript庫,所以,它在客戶端執行。

而,Sass, 需要Ruby,在伺服器端執行。許多開發人員不選擇LESS因為在瀏覽器裡Javascript解析less程式碼返回CSS程式碼需要額外的時間。有幾個方 法可以避免這個問題。一個是隻在開發階段使用LESS。一旦開發完成,我把LESS轉化成CSS程式碼,放在另外一個檔案裡,在引用less檔案的地方引用 這個css檔案。另一個方法是使用

LESS.app來編譯和最小化你的LESS檔案。這兩種方法,都可以減少對style的影響,並且可以避免瀏覽器不能執行JavaScript帶來的問題。雖然可能性很小,但總是有可能的。

更 新:上面的論述引起了熱烈的討論,甚至在Twitter上也有相關的爭論。請大家同時也考慮Adam Stacoviak的回覆“現實是Sass需要Ruby,但是,它並不一定要在Server端轉化成CSS。它可以本地編譯(就像LESS聲稱的一樣), 並且編譯過的CSS也可以和之前的CSS一樣使用。因為這裡是Smashing Magazine,讀者一定非常多,我猜這裡有很大一部分讀者正在使用Mac來讀這篇文章。那麼,所有的Mac電腦都預設支援Ruby,所以安裝、執行 Sass只需要一個命令列 (sudo gem install sass)”。

一旦你安裝了Sass,你就可以在本地把Sass編譯成CSS,並且在你的專案裡引用這個CSS。如果你不知道如何開始使用Sass(或者Compass),那麼你可以讀讀這篇文章:“Getting Started with Sass and Compass”。感謝Adam指出問題。

Less Is More

安裝

在你的專案使用LESS非常的容易:

2. 建立一個樣式表,比如叫style.less

3. 新增下面程式碼到HTML的<head>塊裡

注 意link標籤的ref屬性。你需要以“/less”結尾,才能工作。緊跟在link標籤的後面,要包含這個script標籤。如果你使用的是HTML5 的語法,那麼你可以去掉 type="text/css" 和 type="text/javascript" 這兩句。

變數(Variables)

如 果你是一個developer,變數是你最好的朋友。當你需要多次使用同一個資訊的時候(比如字型,顏色),把它設定成一個變數就是情理之中的事兒了。通 過這種方法,保證了一致性,並且不用翻遍檔案來找一個十六進位制的數字複製貼上了。甚至你還可以對這個十六進位制數進行加減運算。比如說:

@blue: #00c;
@light_blue: @blue + #333;
@dark_blue: @blue - #333;

如果我們把這3個顏色應用到三個div上,我們就可以看到一個顏色漸進的效果:

1.png

應用的順序是:@light_blue 、@blue、@dark_blue

LESS和Sass定義變數唯一的不同就是Less使用@,Sass使用$。 還有一些作用域的不同,後面我會簡要介紹一下。

混合(Mixins)

有時候,我們希望建立一些樣式,可以在整個樣式表裡重複使用。你可以再HTML裡給這些元素新增相同的class,而使用LESS,只修改CSS也可以完成這樣的功能。舉個例子,在頁面上有兩個元素要使用一個相同的style:

.border {
border-top: 1px dotted #333;
}

article.post {
background: #eee;
.border;
}

ul.menu {
background: #ccc;
.border;
}

上面的程式碼,實現了和在HTML裡給這兩個元素都加上class ".bordered"類似的功能,而這樣做,你就不需要修改HTML了。效果也很好:

2.png

兩個元素都有了border-top的樣式

而在Sass裡,你需要先使用@mixin定義一個樣式。之後,使用@include來呼叫它:

@mixin border {
border-top: 1px dotted #333;
}

article.post {
background: #eee;
@include border;
}

ul.menu {
background: #ccc;
@include border;
}

帶引數的混合(Parametric Mixins)

就好像在CSS中使用function,會對優化那些看起來重複冗長的CSS很有幫助。一個最有用的例子就是,我們在使用CSS3的過程中,有些樣式需要使用不同的字首才能支援不同的瀏覽器。Nettuts+上有一篇非常好的文章,Jeffrey Way寫的,wonderful webcast and article,裡面介紹了很多解決常用的CSS3屬性字首問題的mixins方法。舉個例子,對於最簡單的圓角:

.border-radius( @radius: 3px ) {
-webkit-border-radius: @radius;
-moz-border-radius: @radius;
border-radius: @radius;
}

在這種情況下,.border-radius這個class就預設有3px的圓角,你還可以在呼叫時傳入其他的值,如果使用.border-radius(10px),那麼圓角就是10px。

在Sass裡的語法和在LESS裡類似,只是要使用$來定義變數,並且先使用@mixin定義一個樣式。再使用@include來呼叫它。

選擇器繼承(Selector Inheritance)

這是一個LESS沒有的功能。使用這個功能,你可以使用@extend方法把一個selector的樣式新增到另一個selector裡。

.menu {
     border: 1px solid #ddd;
}

.footer {
     @extend .menu;
}

/* will render like so: */
.menu, .footer {
     border: 1px solid #ddd;
}

巢狀的規則(Nested Rules)

在CSS裡巢狀的class和id是解決樣式之間互相影響的唯一辦法。但是這樣寫很麻煩。比如使用一個這樣的selector

#site-body .post .post-header h2

是很不爽的,而且浪費空間。使用LESS,你就可以更高效的巢狀id,class和元素。比如上面的例子,你就可以寫成這樣:

#site-body { …

    .post { …

        .post-header { …

            h2 { … }

            a { …

                 &:visited { … }
                 &:hover { … }
            }
        }
    }
}

這段程式碼和上面那段醜陋的CSS程式碼功能是相同的,但是更易讀,並且佔用空間更少。並且,你還可以使用&符號來引用當前所在的元素,就像JavaScript裡的this一樣。

運算(Operations)

你可能期望有這樣的功能:在你的樣式表中可以對常數或者變數進行計算。

@base_margin: 10px;
@double_margin: @base_margin * 2;

@full_page: 960px;
@half_page: @full_page / 2;
@quarter_page: (@full_page / 2) / 2;

對於@quarter_page這個變數,我知道我可以直接除以4,但是我希望借這個機會闡述一下括號的用法,括號用來調整執行順序的規則在這裡也適用。如果樣式包含多個屬性,那括號也是必須的,例如:border: (@width / 2) solid #000。

Sass 在計算數字方面比LESS更加強大。它在內部自帶一個各種單位的轉換表。Sass可以對未知的度量單位進行計算,並且打印出結果。This feature was apparently introduced in an attempt to future-proof the library against changes made by the W3C.

/* Sass */
2in + 3cm + 2pc = 3.514in

/* LESS */
2in + 3cm + 2pc = Error

顏色方法(Color Functions)

前 面我們提到LESS幫助我計算出一個顏色的組合。這個功能是顏色方法的一部分。假設,在你的樣式中,使用一個標準的藍色,你希望在一個“提交”按鈕上使用 這個顏色,並做成漸變效果。你可以開啟Photoshop或者其他什麼圖片編輯器,來得到這個藍色漸變需要的更深或者更淺的藍色,你也可以直接使用 LESS提供的顏色方法:

@blue: #369;

.submit {
    padding: 5px 10px;
    border: 1px solid @blue;
    background: -moz-linear-gradient(top, lighten(@blue, 10%), @blue 100%); /*Moz*/
    background: -webkit-gradient(linear, center top, center bottom, from(lighten(@blue, 10%)), color-stop(100%, @blue)); /*Webkit*/
    background: -o-linear-gradient(top, lighten(@blue, 10%) 0%, @blue 100%); /*Opera*/
    background: -ms-linear-gradient(top, lighten(@blue, 10%) 0%, @blue 100%); /*IE 10+*/
    background: linear-gradient(top, lighten(@blue, 10%) 0%, @blue 100%); /*W3C*/
    color: #fff;
    text-shadow: 0 -1px 1px rgba(0,0,0,0.4);
}

這 個lighten方法可以先行的使某個顏色變數多少百分比。在上面的程式碼裡,它會使標準藍色變亮10%。這個方法讓我們可以方便的改變漸變元素的顏色,也 可以方便的改變基準顏色。這為我們支援多主題提供的巨大的幫助。另外,如果你使用帶引數的方法,就像上面的例子那樣,你可以把瀏覽器字首封裝在一個方法 裡,這樣你就可以簡單的寫成這樣:

.linear-gradient(lighten(@blue), @blue, 100%);

你可以得到這樣的效果:

Image.png

還有很多其他的方法,改變顏色的深度,飽和度,甚至轉變成另外一個顏色。我建議大家自己試試,看能做出什麼效果。

Sass似乎提供了更多的顏色選項——但我並不經常用到他們。變深和變淺是我最常用到的方法。更多的細節,可以參考這篇文章:in-depth article on the topic

條件語句和控制(Conditionals and Control)

這個功能非常棒,但是LESS並不支援。使用Sass,你可以使用if {} else {} 語句,並且可以使用for{}迴圈。它還支援and,or和not關鍵字,還支援<, >, <=, >=和==等運算子。

/* Sample Sass "if" statement */
@if lightness($color) > 30% {
  background-color: #000;
} @else {
  background-color: #fff;
}

/* Sample Sass "for" loop */
@for $i from 1px to 10px {
  .border-#{i} {
    border: $i solid blue;
  }
}

名稱空間(Namespaces)

我們可以使用名稱空間組織樣式的層次結構,LESS允許我們建立一組經常被使用的樣式,並且可以在其他地方呼叫它們。比如,我們建立了一組樣式,叫defaults,當某些元素需要使用這些樣式的時候,就可以從這個組裡面取。

#defaults {
     .nav_list () {
          list-style: none;
          margin: 0; padding: 0;
     }
     .button () { … }
     .quote () { … }
}

在後面的程式碼裡,如果有個nav元素裡的ul需要使用某個預設樣式,我們簡單的呼叫它就可以了:

nav ul {
     #defaults > .nav_list;
}

作用域(Scope)

作用域在程式設計過程中非常重要,同樣在LESS中也很重要。如果你在根級別定義了一個變數,那麼你可以在文件的任何一個地方呼叫它。如果你在一個selector裡定義了一個同名的變數,那麼它會覆蓋上級的變數,並且只有在這個selector裡才能取到這個值。

@color: #00c; /* blue */

#header {
     @color: #c00; /* red */

     border: 1px solid @color; /* will have a red border */
}

#footer {
     border: 1px solid @color; /* will have a blue border */
}

因為我們在#header裡重新定義了這個變數,所以在這個變數在這個selector裡的取值和外面不一樣。在這個selector之前和之後的呼叫,都會保留外面的值。

LESS對作用域的處理和Sass有一點不同。對於上面的程式碼,一旦@color變成red,那麼後面的所有程式碼都會被解釋成red。

註釋(Comments)

這部分非常基礎,LESS支援兩種註釋型別。標準的CSS註釋,/* comment */,它可以通過LESS的處理並且被輸出。單行的註釋:// comment,但是並不會被輸出,所以,這種註釋是“無聲的”。

匯入(Importing)

導 入也是一個必須的功能。標準的@import: 'classes.less'在LESS下可以工作。如果你匯入的也是一個LESS檔案,那麼字尾名可以省略不寫,所以可以寫成@import 'classes'。如果你要引入的檔案不需要LESS進行處理,那麼就需要寫上字尾名,比如.css(例如:@import: 'reset.css')。

字串插入(String Interpolation)

樣式裡可以插入字串變數:

@base_url = 'http://coding.smashingmagazine.com';/
background-image: url("@{base_url}/images/background.png");

轉義(Escaping)

如果你要使用一個不合法的CSS語法,或者LESS不能識別的語法,這個轉義功能就很重要了。通常,使用這個功能是做一個瘋狂的Microsoft Hack。為了避免LESS拋異常,你需要對它們進行轉義:

.class {
     filter: ~"progid:DXImageTransform.Microsoft.Alpha(opacity=20)";
}

/* Will actually be outputted like this: */
.class {
     filter: progid:DXImageTransform.Microsoft.Alpha(opacity=20);
}

Javascript求值(JavaScript Evaluation)

這是我最喜歡的LESS的功能:在樣式表裡使用Javascript功能——太好了。你可以使用表示式,並且可以引用環境變數,Javascript程式碼需要在`符號中間:

@string: `'howdy'.toUpperCase()`; /* @string becomes 'HOWDY' */

/* You can also use the previously mentioned interpolation: */
@string: 'howdy';
@var: ~`'@{string}'.topUpperCase()`; /* becomes 'HOWDY' */

/* Here we access part of the document */
@height = `document.body.clientHeight`;

輸出格式(Output Formatting)

LESS沒有提供輸出設定,Sass提供4中輸出格式:嵌入式的、緊湊的、壓縮的、展開的。

寫在最後

這 兩個框架有很多共同點。對於那些寫程式碼的實際設計師來說,他們都是強大的工具,來幫助開發人員更高效更快速的工作。如果你是一個Ruby或者HAML的粉 絲,那麼Sass可能用起來更順手。對我這樣一個Javascript和PHP的geek來說,我更喜歡LESS,因為它可以方便的包含和執行 Javascript表示式。我不是很確定在我真的理解了如何在我的樣式表裡使用它們是最好的,但是我正在嘗試。如果你曾經用過它們中的某一個或者兩個, 我希望能聽到你們的反饋。歡迎大家來交流使用方法,技巧,或者對我這篇文章的糾錯。

額外的參考文獻: