摘要:變量插值預(yù)處理器中定義的變量不僅可以用作屬性值,還可以用作選擇器,屬性名等,這就是變量插值。三種預(yù)處理器的嵌套語法是一致的,引用父級選擇器的標(biāo)記也相同。三種預(yù)處理器的使用方式的差異比較大,下面分別說明。
在寫CSS的時候我們會發(fā)現(xiàn),為了兼容瀏覽器等原因,我們往往需要寫很多冗余的代碼,CSS預(yù)處理器就是為了解決CSS的這些問題,簡化CSS代碼的編寫。
目前最主流的CSS預(yù)處理器是LESS、SASS和Stylus,最近花了幾天時間學(xué)習(xí)并使用了它們,于是就想對這三個預(yù)處理器做個比較。根據(jù)這三種語言的特性,主要從一下幾個方面進行討論:
基本語法
變量
嵌套
混入(mixin)
繼承
函數(shù)
@import
運算符
邏輯控制
基本語法LESS的基本語法和CSS差不多,SASS和Stylus都可以利用縮進代替花括號,并且空格有重要的意義。SASS保存為".sass"是縮進格式,保存為".scss"是非縮進格式。SASS一般使用".scss"擴展名。LESS的擴展名為".less",Stylus的擴展名為".styl"。
注意:SASS依賴于Ruby,安裝前必須先安裝Ruby。
LESS & SCSS:
ul { list-style: none; }
SASS:
ul list-style: none
Stylus:
ul list-style none
注意:以下SASS代碼都以擴展名為".scss"的方式書寫。
變量CSS預(yù)處理器中可以定義變量,并且可以在樣式表中使用,變量類型沒有限制,這樣就可以一定程度上減少CSS中無法避免的重復(fù)問題。
LESS變量名必須以@符號開頭,變量名和變量值之間以冒號隔開。有個問題是@規(guī)則在CSS中算是一種原生的擴展方式,變量名用@開頭很可能會和以后CSS中的新@規(guī)則沖突。
@orange: #feb914; header { background-color: @orange; }
SASS變量名必須以$開始,變量名和變量值之間以冒號隔開。
$orange: #feb914; header { background-color: $orange; }
Stylus對變量名沒有任何限定,變量名與變量值之間可以用冒號、空格和等號隔開。
bgorange = #feb914; header background-color bgorange
上面三種不同的寫法都會產(chǎn)生相同的結(jié)果:
header { background-color: #feb914; }
Stylus還有一個獨特功能,它不需要分配值給變量就可以定義引用屬性。如下:
#logo position: absolute top: 50% left: 50% width: w = 150px height: h = 80px margin-left: -(w / 2) margin-top: -(h / 2)
#logo position: absolute top: 50% left: 50% width: 150px height: 80px margin-left: -(@width / 2) margin-top: -(@height / 2)變量作用域
三種預(yù)處理器中定義的變量都是有作用域的,查找變量的順序是先在局部定義中查找,如果找不到,則逐級向上查找。
如果我們在代碼中重寫某個已經(jīng)定義的變量,Less的處理邏輯和其他兩個有區(qū)別。Less中,這個行為叫懶加載(Lazy Loading)。注意Less中所有變量的計算,都是以這個變量最后一次被定義的值為準。
LESS:
@size: 40px; .content { width: @size; } @size: 60px; .container { width: @size; }
編譯輸出為:
.content { width: 60px; } .container { width: 60px; }
在SASS中情況如下:
$size: 40px; .content { width: $size; } $size: 60px; .container { width: $size; }
編譯輸出為:
.content { width: 40px; } .container { width: 60px; }
Stylus和SASS行為相同,變量的計算以變量最近一次的定義為準。
變量插值預(yù)處理器中定義的變量不僅可以用作屬性值,還可以用作選擇器,屬性名等,這就是變量插值。
變量名插值Less中支持以@@var的形式引用變量,即該變量的名字是由@var的值決定的。
選擇器插值以類選擇器為例
LESS:
@way: new; .@{way}-task { font-size: 18px; }
SASS:
$way: new; .#{$way}-task { font-size: 18px; }
Stylus:
way: new; .{way}-task font-size 18px
解析結(jié)果都是:
.new-task { font-size: 18px; }
注意:在Less中,通過選擇器插值生成的規(guī)則無法被繼承。
@import插值Sass中只能在使用url()表達式時進行變量@import插值:
$device: mobile; @import url(styles.#{$device}.css);
Less中可以在字符串中進行插值:
@device: mobile; @import "styles.@{device}.css";
Stylus中沒有@import插值,但是可以利用其字符串拼接的功能實現(xiàn):
device = "mobile" @import "styles." + device + ".css"屬性名插值
三個預(yù)處理器均支持屬性名插值,使用方式且和上述插值類似。
嵌套如果需要在相同的父元素中選擇多個子元素,需要一遍又一遍地寫父元素,如果用CSS預(yù)處理器就可以不用重復(fù)寫父元素,并且父元素和子元素的關(guān)系一目了然。
三種預(yù)處理器的嵌套語法是一致的,引用父級選擇器的標(biāo)記&也相同。除了&,Sass和Stylus還分別用@at -root和"/"符號作為嵌套時根規(guī)則集的選擇器引用。首先以LESS為例討論嵌套語法:
#sort { margin-top: 24px; ul { margin-left: 8px; line-height: 36px; vertical-align: middle; } } input { width: 80px; &:-ms-input-placeholder { font-size: 16px; color: @white; } }
編譯結(jié)果為:
#sort { margin-top: 24px; } #sort ul { margin-left: 8px; line-height: 36px; vertical-align: middle; } input { width: 80px; } input:-ms-input-placeholder { font-size: 16px; color: @white; }
SASS還提出了屬性嵌套,屬性嵌套指的是有些屬性擁有相同的開始單詞,如border-width,border-color都是以border開頭。官網(wǎng)的實例如下:
.fakeshadow { border: { style: solid; left: { width: 4px; color: #888; } right: { width: 2px; color: #ccc; } } }
生成的CSS為:
.fakeshadow { border-style: solid; border-left-width: 4px; border-left-color: #888; border-right-width: 2px; border-right-color: #ccc; }混入(mixin)
mixins有點像C語言中的宏,當(dāng)某段CSS經(jīng)常需要在多個元素中使用時,可以為這些共用的CSS定義一個mixin,然后只需要在需要引用這些CSS地方調(diào)用該mixin即可。
三種預(yù)處理器的mixin使用方式的差異比較大,下面分別說明。
LESS混入方式如下:
.my-mixin { color: black; } .my-other-mixin() { background: white; } .my-hover-mixin() { &:hover { border: 1px solid red; } } .border-radius(@radius: 5px) { -webkit-border-radius: @radius; -moz-border-radius: @radius; border-radius: @radius; } .class { .my-mixin; .my-other-mixin; } button { .my-hover-mixin(); } #header { .border-radius(4px); } .button { .border-radius; }
編譯輸出為:
.my-mixin { color: black; } .class { color: black; background: white; } button:hover { border: 1px solid red; } #header { -webkit-border-radius: 4px; -moz-border-radius: 4px; border-radius: 4px; } .button { -webkit-border-radius: 5px; -moz-border-radius: 5px; border-radius: 5px; }
LESS的mixin需要注意的是同名的mixin不是后面的覆蓋前面的,而是會累加輸出。這就會產(chǎn)生一個問題,如果存在和mixin同名的class樣式,并且mixin沒有參數(shù),則在調(diào)用時會把對應(yīng)的class樣式一起輸出,這顯然不是我們所需要的。
SASS的mixin用法如下:
@mixin center-block { margin-left:auto; margin-right:auto; } .demo{ @include center-block; } @mixin horizontal-line($border:1px dashed #ccc, $padding:10px){ border-bottom:$border; padding-top:$padding; padding-bottom:$padding; } .imgtext-h li{ @include horizontal-line(1px solid #ccc); }
編譯結(jié)果為:
.demo{ margin-left:auto; margin-right:auto; } .imgtext-h li { border-bottom: 1px solid #cccccc; padding-top: 10px; padding-bottom: 10px; }
Sass用@mixin和@include兩個指令清楚地說明了mixin的定義和引用方式。
Stylus的mixin和Sass的類似:
border-radius(n) -webkit-border-radius n -moz-border-radius n border-radius n form input[type=button] border-radius 5px繼承
繼承其實和混入的作用差不多,那為什么還需要繼承呢?混入確實很好用,但是如果多個地方都混入同樣的代碼,會造成代碼的重復(fù)。例如:
.block { margin: 10px 5px; padding: 2px; } p { .block; border: 1px solid #EEE; }
會輸出:
.block { margin: 10px 5px; padding: 2px; } p { margin: 10px 5px; padding: 2px; border: 1px solid #EEE; }
而我們期望的輸出實際是:
.block, p { margin: 10px 5px; padding: 2px; } p { border: 1px solid #EEE; }
用繼承就可以實現(xiàn)上面的輸出,不會有重復(fù)的代碼(以SASS為例):
.block { margin: 10px 5px; padding: 2px; } p { @extend .block; border: 1px solid #EEE; }
Stylus的繼承來源于SASS,兩者使用方式相同。而LESS則用偽類來實現(xiàn)繼承:
.block { margin: 10px 5px; padding: 2px; } p { &:extend(.block); border: 1px solid #EEE; }
Less默認只繼承父類本身的樣式,如果要同時繼承嵌套定義在父類作用域下的樣式,得使用關(guān)鍵字all,比如&:extend(.block all)。
函數(shù)三種預(yù)處理器都有自己的內(nèi)置函數(shù),例如顏色處理,類型判斷等。LESS中不能自定義函數(shù),SASS和Stylus可以。
SASS自定義函數(shù)用法如下,需要使用@function,并用@return指令返回結(jié)果:
@function pxToRem($px) { @return $px / 2; } body{ font-size: pxToRem(32px); }
Stylus中則無需這些指令:
pxToRem(n) n / 2 body font-size: pxToRem(32px)@import
@import的作用是從其他樣式表導(dǎo)入樣式,三種預(yù)處理器的@import的使用方式各不相同。
除了基本的功能外,LESS引入了import選項來擴展@import的語法。語法如下:
@import (keyword) "filename";
其中keyword可以是如下幾種選項(可以聯(lián)合使用)。
1.reference:使用一個外部文件參與編譯,但不輸出其內(nèi)容。
2.inline:直接將引入的文件放入輸出文件中,但不處理這個引入的文件。
3.less:不管文件擴展名是什么都將該文件作為一個LESS文件處理。
4.css:不管文件擴展名是什么都將該文件作為一個CSS文件處理。
5.once:只引入文件一次(去重),這是默認方式。
6.multiple:可以引入文件多次。
SASS則沒有LESS的這些擴展語法,它自己推斷引入的方式。它的@import 不會被去重,多次引入會導(dǎo)致一個樣式文件被多次輸出到編譯結(jié)果中。
Stylus的@import和SASS一樣都是自己推斷引入的方式,但是Stylus可以進行引入文件的去重,它有一個自定義的指令@require,用法和@import一樣,但引入的文件只會編譯一次。
運算符三種預(yù)處理器都具有運算的特性,可以對數(shù)值型的Value(如:數(shù)字、顏色、變量等)進行加減乘除四則運算。
Stylus的中文文檔中,詳細討論了Stylus的運算符
Sass中通過@iF 、@else 實現(xiàn)條件判斷來提供語言的流控制,通過@for、@each、@while實現(xiàn)循環(huán),然后配合map和list這兩種數(shù)據(jù)類型可以實現(xiàn)多數(shù)編程語言提供的功能。
SASS中還實現(xiàn)了一個三目判斷,語法為:if($condition, $if_true, $if_false) 。三個參數(shù)分別表示:條件,條件為真的值,條件為假的值。
Stylus中通過if、else if、else、unless(基本與if相反)實現(xiàn)條件判斷來提供語言的流控制,通過for/in實現(xiàn)循環(huán)迭代。
而LESS中沒有上述復(fù)雜的語法,只通過guarded mixins代替if/else實現(xiàn)簡單的條件判斷。舉例如下:
.mixin (@a) when (lightness(@a) >= 50%) { background-color: black; } .mixin (@a) when (lightness(@a) < 50%) { background-color: white; } .mixin (@a) { color: @a; }
以上就是三種CSS預(yù)處理器的主要區(qū)別,實際項目中使用哪種CSS預(yù)處理器還需要自己斟酌,多踩坑才能體會到哪種預(yù)處理器最適合你當(dāng)前的項目。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/115379.html
摘要:它們有個統(tǒng)一的名字預(yù)處理器。面對以上問題,預(yù)處理器給出了非常可行的解決方案變量就像其他編程語言一樣,免于多處修改。回到話題中,之所以會出現(xiàn)向預(yù)處理器這樣子的解決方案,歸根結(jié)底還是標(biāo)準發(fā)展的滯后性導(dǎo)致的。 前言 現(xiàn)在的前端,javascript的發(fā)展有目共睹,框架林立。同時,html也是齊頭并進,推出了HTML5標(biāo)準,并且得到了普及。這樣的發(fā)展卻唯獨少了一個角色? CSS,就是這個看似不...
摘要:它們有個統(tǒng)一的名字預(yù)處理器。面對以上問題,預(yù)處理器給出了非常可行的解決方案變量就像其他編程語言一樣,免于多處修改。回到話題中,之所以會出現(xiàn)向預(yù)處理器這樣子的解決方案,歸根結(jié)底還是標(biāo)準發(fā)展的滯后性導(dǎo)致的。 前言 現(xiàn)在的前端,javascript的發(fā)展有目共睹,框架林立。同時,html也是齊頭并進,推出了HTML5標(biāo)準,并且得到了普及。這樣的發(fā)展卻唯獨少了一個角色? CSS,就是這個看似不...
摘要:狀態(tài)偽類是基于元素當(dāng)前狀態(tài)進行選擇的。在與用戶的交互過程中元素的狀態(tài)是動態(tài)變化的,因此該元素會根據(jù)其狀態(tài)呈現(xiàn)不同的樣式。單冒號用于偽類,雙冒號用于偽元素。可以通過對父元素添加偽類撐開父元素高度,因為就是其最后一個子元素。 css選擇器常見包括id(#id)、標(biāo)簽(tag)、class(.class)、屬性[attr=attrval]等,還包括偽元素和偽類選擇器。正確的利用偽元素和偽類能...
摘要:狀態(tài)偽類是基于元素當(dāng)前狀態(tài)進行選擇的。在與用戶的交互過程中元素的狀態(tài)是動態(tài)變化的,因此該元素會根據(jù)其狀態(tài)呈現(xiàn)不同的樣式。單冒號用于偽類,雙冒號用于偽元素。可以通過對父元素添加偽類撐開父元素高度,因為就是其最后一個子元素。 css選擇器常見包括id(#id)、標(biāo)簽(tag)、class(.class)、屬性[attr=attrval]等,還包括偽元素和偽類選擇器。正確的利用偽元素和偽類能...
閱讀 3518·2023-04-25 17:35
閱讀 2594·2021-11-24 09:39
閱讀 2530·2021-10-18 13:32
閱讀 3415·2021-10-11 10:58
閱讀 1637·2021-09-26 09:55
閱讀 6152·2021-09-22 15:47
閱讀 967·2021-08-26 14:15
閱讀 3472·2019-08-30 15:55