Css可以讓你做很多事情,但它畢竟是給浏覽器認的東西,對開發者來說,Css缺乏很多特性,例如變量、常量以及一些編程語法,代碼難易組織和維護。這時Css預處理器就應運而生了。Css預處理器定義了一種新的語言將Css作為目標生成文件,然後開發者就只要使用這種語言進行編碼工作了。預處理器通常可以實現浏覽器兼容,變量,結構體等功能,代碼更加簡潔易於維護。 “我應該選擇哪種css預處理器?”是最近網上的一大熱門話題,很多人為此爭論不休。相比過去我們對是否應該使用Css預處理器的話題,這已經是很大的進步了。目前比較流行的兩種預處理器是Sass和Less。
至於他們誰更優秀一些:簡短的答案是:Sass
稍長一點的答案:Sass比其他任何預處理器語言都好,但如果你正在使用Less,這也很酷!這可以證明你正在使用預處理器來寫幫助自己寫更好的代碼。
非常長的答案:請繼續往下看
使用Css預處理器唯一真正需要學習的只有語法,SASS是Ruby語言寫的,但是兩者的語法沒有關系。不懂Ruby,照樣可以使用。你需要的只是一個像CudeKit的應用來觀察和編譯你所撰寫的文件。 Less就更不用了,只需要調用一個js即可(在客戶端運行),或者借助Node.js(服務器運行)。
獲勝者:無。
Css3提供了很多新特性,比如漸變、動畫、圓角等等,但是在使用這些高級特性的時候,我們往往需要編寫( -moz-、-webkit-、-ms- …)。不論Sass和Less,你都可以用自己的混合來編寫。但是在項目中當我們需要修改這些繁瑣的前綴時,我們如何不用返回每一行代碼並且更新它們?你大概也不會更新手工混合的文件。但是在Sass中,我們可以使用開源的Css框架,會自動更新並自動處理浏覽器前綴。我們只需要保持更新,外加偶爾按一下編譯鍵,它就會幫助我們自動處理所有的前綴問題,毫不費力。( -moz-、-webkit-、-ms- …)。不論Sass和Less,你都可以用自己的混合來編寫。但是在項目中當我們需要修改這些繁瑣的前綴時,我們如何不用返回每一行代碼並且更新它們?你大概也不會更新手工混合的文件。但是在Sass中,我們可以使用開源的Css框架,會自動更新並自動處理浏覽器前綴。我們只需要保持更新,外加偶爾按一下編譯鍵,它就會幫助我們自動處理所有的前綴問題,毫不費力。
獲勝者:Sass。
Less可以做防御型混合,這種混合只在條件為真的情況下生效。比如你想根據文本顏色來設置背景色,當文本色比較淺的時候背景色很深,文本色比較深的時候背景色很淺。那麼你就得把混合分成兩部分,以確保有一種情況條件為真,使混合生效。
.set-bg-color (@text-color) when (lightness(@text-color) >= 50%) { background: black; } .set-bg-color (@text-color) when (lightness(@text-color) < 50%) { background: #ccc; }
然後就可以得到想要的背景:
.box-1 { color: #BADA55; .set-bg-color(#BADA55); }
Less模擬循環和遞歸:
.loopingClass (@index) when (@index > 0) { .myclass { z-index: @index; } // 遞歸 .loopingClass(@index - 1); } // 停止循環 .loopingClass (0) {} // 輸出 .loopingClass (3);
生成的css代碼:
.myclass {z-index: 3;} .myclass {z-index: 2;} .myclass {z-index: 1;}
但這也就是Less全部的邏輯和循環處理能力了,而Sass具有真正的語言處理能力。包括if/then/else、for循環、while循環,函數等等。
真正的For循環:
@for $i from 1 through 3{ .item-#{$i}{ width:100px*$i; } }
Css:
.item-1{width:100px;} .item-2{width:200px;} .item-3{width:300px;}
例如Compass框架有一個叫“background”的混合,它會給你所有你需要的和想要的,並且兼容所有浏覽器的代碼。
簡潔易懂的代碼:
.bam { @include background( image-url("foo.png"), linear-gradient(top left, #333, #0c0), radial-gradient(#c00, #fff 100px) ); }
現在輪到這個怪物了(不幸的是,我們需要它,看看我們會得到的Css代碼吧):
.bam { background: url('/foo.png'), -webkit-gradient(linear, 0% 0%, 100% 100%, color-stop(0%, #333333), color-stop(100%, #00cc00)), -webkit-gradient(radial, 50% 50%, 0, 50% 50%, 100, color-stop(0%, #cc0000), color-stop(100%, #ffffff)); background: url('/foo.png'), -webkit-linear-gradient(top left, #333333, #00cc00), -webkit-radial-gradient(#cc0000, #ffffff 100px); background: url('/foo.png'), -moz-linear-gradient(top left, #333333, #00cc00), -moz-radial-gradient(#cc0000, #ffffff 100px); background: url('/foo.png'), -o-linear-gradient(top left, #333333, #00cc00), -o-radial-gradient(#cc0000, #ffffff 100px); background: url('/foo.png'), -ms-linear-gradient(top left, #333333, #00cc00), -ms-radial-gradient(#cc0000, #ffffff 100px); background: url('/foo.png'), linear-gradient(top left, #333333, #00cc00), radial-gradient(#cc0000, #ffffff 100px); }
獲勝者:Sass
當你聲明一個包涵一些樣式的類之後,你想要另外一個和它只有少許不同的類,在less中你可以這樣寫
.module-a{ color:#333; } .module-b { .module-a(); /* 把module-a所有的css代碼拷貝到這裡 */ border: 1px solid red; }
這樣.module-b便繼承了.module-a的所有屬性 生成的Css代碼:
.module-a{ color:#333; } .module-b { color:#333; border: 1px solid red; }
這在本質上就是繼承,在Sass中也可以做同樣的事情。但Sass的"@extend"更好一些,在"@extend"中.module-a的樣式不僅僅是被復制到.module-b(可以擴展)中,在Css中對.module-a的定義被修改為.module-a,.module-b(這樣做選擇器的效率更高)。
Sass代碼
.module-a { /* 一堆css代碼 */ } .module-b { /* 一些覆蓋和擴展代碼 */ @extend .module-a; }
最終編譯Css代碼
.module-a, .module-b { /* 一堆css代碼 */ } .module-b { /* css代碼*/ }
結果是Sass重寫的選擇器效率更高 獲勝者:Sass
變量前綴:less使用"@",sass使用"$"。在css中@符號有繼承的意義,而美元符號沒有。我們可以說這個是個人喜好。但是沒有混淆概念的Sass在這裡更有優勢。 不過Sass的變量范圍有些古怪,如果你在局部環境中重寫了一個全局變量,全局變量的值會被改變。
$color: black; .scoped { $color: white; color: $color; } .unscoped { // LESS = black (仍然是一開始定義的值black) // SASS = white (被改寫為white) color: $color; }
獲勝者:Less
我們開始使用媒體查詢的方式是在主樣式表的底部加入針對媒體查詢的媒體代碼塊。這樣做很有用,但是它會導致響應的樣式和原有的樣式風格脫節。 CSS代碼:
.some-class { /* 基礎樣式 */ } /* 很多行以後 */ @media (max-width: 800px) { .some-class { /* 響應樣式 */ } }
通過Sass或者Less,我們可以用嵌套把他們寫到一起:
.some-class { /* 基礎樣式 */ @media (max-width: 800px) { /* 響應樣式 */ } }
通過Sass,我們甚至可以更牛逼一點,用一種更酷的寫法:
=respond-to($name) @if $name == small-screen @media only screen and (min-width: 320px) @content @if $name == large-screen @media only screen and (min-width: 800px) @content
然後,我們可以通過這種技術使代碼更加簡潔和語義化
.column width: 25% +respond-to(small-screen) width: 100%
需要Sass 3.2的環境(安裝方法,在Start Command Prompt with Ruby中輸入“gem install sass –pre”)
在大多數情況下,數學運算都是很相似的。但是sass和less在處理單位的適合還有些不同。例如less會假設第一個單位是你想要的,忽略後一個:
div { width: 100px + 2em; // == 102px (怪異之處) }
但是在Sass中,你會得到一個明確的錯誤提示:不兼容的單位"px"和"em"。我想是否應該提示錯誤是值得商榷的,但是相比之下我更希望得到錯誤,特別是當我在處理難以追查的變量的時候。 sass允許我們使用未知單位,但是less不可以。同時它們還有一些其他的不同之處,比如sass如何為有單位的值做乘法,但這些都過於簡單,不值得繼續討論。
勝利者:Sass
綜上,雖然Sass比less稍難上手,但如果要使用Css預處理器的話,多花點時間在Sass上面是值得的。
英文原文:http://css-tricks.com/sass-vs-less/
參考資料:http://sass-lang.com/