聲明變量
定義變量的語(yǔ)法:
在有些編程語(yǔ)言中(如,JavaScript)聲明變量都是使用關(guān)鍵詞“var”開(kāi)頭,但是在 Sass 不使用這個(gè)關(guān)鍵詞,而是使用大家都喜歡的美元符號(hào)“$”開(kāi)頭。我想用一張圖來(lái)解釋,我一直堅(jiān)信,一圖勝千言萬(wàn)語(yǔ):
來(lái)看一個(gè)簡(jiǎn)單的示例,假設(shè)你的按鈕顏色可以給其聲明幾個(gè)變量:
$brand-primary : darken(#428bca, 6.5%) !default; // #337ab7
$btn-primary-color : #fff !default;
$btn-primary-bg : $brand-primary !default;
$btn-primary-border : darken($btn-primary-bg, 5%) !default;
如果值后面加上!default則表示默認(rèn)值。
注:了解 Bootstrap 的 Sass 版本的同學(xué),就一眼能看出,上面的示例代碼是 Bootstrap 定義 primarybutton 的顏色。
普通變量與默認(rèn)變量
普遍變量
定義之后可以在全局范圍內(nèi)使用。
$fontSize: 12px;
body{
font-size:$fontSize;
}
編譯后的css代碼:
body{
font-size:12px;
}
默認(rèn)變量
sass的默認(rèn)變量?jī)H需要在值后面加上 !default即可。
$baseLineHeight:1.5 !default;
body{
line-height: $baseLineHeight;
}
編譯后的css 代碼:
body{
line-height:1.5;
}
sass 的默認(rèn)變量一般是用來(lái)設(shè)置默認(rèn)值,然后根據(jù)需求來(lái)覆蓋的,覆蓋的方式也很簡(jiǎn)單,只需要在默認(rèn)變量之前重新聲明下變量即可。
$baseLineHeight: 2;
$baseLineHeight: 1.5 !default;
body{
line-height: $baseLineHeight;
}
編譯后的css代碼:
body{
line-height:2;
}
可以看出現(xiàn)在編譯后的 line-height 為 2,而不是我們默認(rèn)的 1.5。默認(rèn)變量的價(jià)值在進(jìn)行組件化開(kāi)發(fā)的時(shí)候會(huì)非常有用。
變量的調(diào)用
定義聲明好變量
$brand-primary : darken(#428bca, 6.5%) !default; // #337ab7
$btn-primary-color: #fff !default;
$btn-primary-bg : $brand-primary !default;
$btn-primary-border : darken($btn-primary-bg, 5%) !default;
在按鈕button 中調(diào)用
.btn-primary {
background-color: $btn-primary-bg;
color: $btn-primary-color;
border: 1px solid $btn-primary-border;
}
編譯出來(lái)后的css:
.btn-primary {
background-color: #337ab7;
color: #fff;
border: 1px solid #2e6da4;
}
局部變量和全局變量
代碼例子:
//SCSS
$color: orange !default;//定義全局變量(在選擇器、函數(shù)、混合宏...的外面定義的變量為全局變量)
.block {
color: $color;//調(diào)用全局變量
}
em {
$color: red;//定義局部變量
a {
color: $color;//調(diào)用局部變量
}
}
span {
color: $color;//調(diào)用全局變量
}
css 的結(jié)果:
//CSS
.block {
color: orange;
}
em a {
color: red;
}
span {
color: orange;
}
上面的示例演示可以得知,在元素內(nèi)部定義的變量不會(huì)影響其他元素。如此可以簡(jiǎn)單的理解成,全局變量就是定義在元素外面的變量,如上代碼第一句:
$color:orange !default;
$color 就是一個(gè)全局變量,而定義在元素內(nèi)部的變量,比如 $color:red; 是一個(gè)局部變量。
除此之外,Sass 現(xiàn)在還提供一個(gè) !global 參數(shù)。!global 和 !default 對(duì)于定義變量都是很有幫助的。我們之后將會(huì)詳細(xì)介紹這兩個(gè)參數(shù)的使用以及其功能。
全局變量的影子
當(dāng)在局部范圍(選擇器內(nèi)、函數(shù)內(nèi)、混合宏內(nèi)...)聲明一個(gè)已經(jīng)存在于全局范圍內(nèi)的變量時(shí),局部變量就成為了全局變量的影子。基本上,局部變量只會(huì)在局部范圍內(nèi)覆蓋全局變量。
上面例子中的 em 選擇器內(nèi)的變量 $color 就是一個(gè)全局變量的影子。
//SCSS
$color: orange !default;//定義全局變量
.block {
color: $color;//調(diào)用全局變量
}
em {
$color: red;//定義局部變量(全局變量 $color 的影子)
a {
color: $color;//調(diào)用局部變量
}
}
什么時(shí)候聲明變量?
我的建議,創(chuàng)建變量只適用于感覺(jué)確有必要的情況下。不要為了某些駭客行為而聲明新變量,這絲毫沒(méi)有作用。只有滿足所有下述標(biāo)準(zhǔn)時(shí)方可創(chuàng)建新變量:
* 該值至少重復(fù)出現(xiàn)了兩次;
* 該值至少可能會(huì)被更新一次;
* 該值所有的表現(xiàn)都與變量有關(guān)(非巧合)。
基本上,沒(méi)有理由聲明一個(gè)永遠(yuǎn)不需要更新或者只在單一地方使用變量。
溫馨小提示:您在學(xué)習(xí) sass 時(shí),除了在我們網(wǎng)頁(yè)上可以做練習(xí),還有一個(gè)便利在線編輯器網(wǎng)址如下:
嵌套-選擇器嵌套
Sass 中還提供了選擇器嵌套功能,但這也并不意味著你在 Sass 中的嵌套是無(wú)節(jié)制的,因?yàn)槟闱短椎膶蛹?jí)越深,編譯出來(lái)的 CSS 代碼的選擇器層級(jí)將越深,這往往是大家不愿意看到的一點(diǎn)。這個(gè)特性現(xiàn)在正被眾多開(kāi)發(fā)者濫用。
選擇器嵌套為樣式表的作者提供了一個(gè)通過(guò)局部選擇器相互嵌套實(shí)現(xiàn)全局選擇的方法,Sass 的嵌套分為三種:
* 選擇器嵌套
* 屬性嵌套
* 偽類嵌套
1、選擇器嵌套
假設(shè)我們有一段這樣的結(jié)構(gòu):
<header>
<nav>
<a href=“##”>Home</a>
<a href=“##”>About</a>
<a href=“##”>Blog</a>
</nav>
<header>
想選中 header 中的 a 標(biāo)簽,在寫(xiě) CSS 會(huì)這樣寫(xiě):
nav a {
color:red;
}
header nav a {
color:green;
}
那么在 Sass 中,就可以使用選擇器的嵌套來(lái)實(shí)現(xiàn):
nav {
a {
color: red;
header & {
color:green;
}
}
}
嵌套-屬性嵌套
Sass 中還提供屬性嵌套,CSS 有一些屬性前綴相同,只是后綴不一樣,比如:border-top/border-right,與這個(gè)類似的還有 margin、padding、font 等屬性。假設(shè)你的樣式中用到了:
.box {
border-top: 1px solid red;
border-bottom: 1px solid green;
}
在 Sass 中我們可以這樣寫(xiě):
.box {
border: {
top: 1px solid red;
bottom: 1px solid green;
}
}
嵌套-偽類嵌套
其實(shí)偽類嵌套和屬性嵌套非常類似,只不過(guò)他需要借助&
符號(hào)一起配合使用。我們就拿經(jīng)典的“clearfix”為例吧:
.clearfix{
&:before,
&:after {
content:"";
display: table;
}
&:after {
clear:both;
overflow: hidden;
}
}
編譯出來(lái)的 CSS:
clearfix:before, .clearfix:after {
content: "";
display: table;
}
.clearfix:after {
clear: both;
overflow: hidden;
}
避免選擇器嵌套:
- 選擇器嵌套最大的問(wèn)題是將使最終的代碼難以閱讀。開(kāi)發(fā)者需要花費(fèi)巨大精力計(jì)算不同縮進(jìn)級(jí)別下的選擇器具體的表現(xiàn)效果。
- 選擇器越具體則聲明語(yǔ)句越冗長(zhǎng),而且對(duì)最近選擇器的引用(&)也越頻繁。在某些時(shí)候,出現(xiàn)混淆選擇器路徑和探索下一級(jí)選擇器的錯(cuò)誤率很高,這非常不值得。
混合宏-聲明混合宏
如果你的整個(gè)網(wǎng)站中有幾處小樣式類似,比如顏色,字體等,在 Sass 可以使用變量來(lái)統(tǒng)一處理,那么這種選擇還是不錯(cuò)的。但當(dāng)你的樣式變得越來(lái)越復(fù)雜,需要重復(fù)使用大段的樣式時(shí),使用變量就無(wú)法達(dá)到我們目了。這個(gè)時(shí)候 Sass 中的混合宏就會(huì)變得非常有意義。在這一節(jié)中,主要向大家介紹 Sass 的混合宏。
1、聲明混合宏
在 Sass 中,使用“@mixin”來(lái)聲明一個(gè)混合宏
不帶參數(shù)混合宏:
@mixin border-radius{
-webkit-border-radius: 5px;
border-radius: 5px;
}
其中 @mixin 是用來(lái)聲明混合宏的關(guān)鍵詞,有點(diǎn)類似 CSS 中的 @media、@font-face 一樣。border-radius 是混合宏的名稱。大括號(hào)里面是復(fù)用的樣式代碼。
帶參數(shù)混合宏:
@mixin border-radius($radius:5px){
-webkit-border-radius: $radius;
border-radius: $radius;
}
復(fù)雜的混合宏:
帶有邏輯關(guān)系
@mixin box-shadow($shadow...) {
@if length($shadow) >= 1 {
@include prefixer(box-shadow, $shadow);
} @else{
$shadow:0 0 4px rgba(0,0,0,.3);
@include prefixer(box-shadow, $shadow);
}
}
這個(gè) box-shadow 的混合宏,帶有多個(gè)參數(shù),這個(gè)時(shí)候可以使用“… ”來(lái)替代。簡(jiǎn)單的解釋一下,當(dāng) $shadow 的參數(shù)數(shù)量值大于或等于“ 1 ”時(shí),表示有多個(gè)陰影值,反之調(diào)用默認(rèn)的參數(shù)值“ 0 0 4px rgba(0,0,0,.3) ”。
注:復(fù)雜的混合宏中的邏輯關(guān)系(@if...@else)后面小節(jié)會(huì)有講解。
混合宏-調(diào)用混合宏
在 Sass 中通過(guò) @mixin 關(guān)鍵詞聲明了一個(gè)混合宏,那么在實(shí)際調(diào)用中,其匹配了一個(gè)關(guān)鍵詞“@include”來(lái)調(diào)用聲明好的混合宏。例如在你的樣式中定義了一個(gè)圓角的混合宏“border-radius”:
@mixin border-radius{
-webkit-border-radius: 3px;
border-radius: 3px;
}
在一個(gè)按鈕中要調(diào)用定義好的混合宏“border-radius”,可以這樣使用:
button {
@include border-radius;
}
這個(gè)時(shí)候編譯出來(lái)的 CSS:
button {
-webkit-border-radius: 3px;
border-radius: 3px;
}
混合宏的參數(shù)--傳一個(gè)不帶值的參數(shù)
Sass 的混合宏有一個(gè)強(qiáng)大的功能,可以傳參,那么在 Sass 中傳參主要有以下幾種情形:
A) 傳一個(gè)不帶值的參數(shù)
在混合宏中,可以傳一個(gè)不帶任何值的參數(shù),比如:
@mixin border-radius($radius){
-webkit-border-radius: $radius;
border-radius: $radius;
}
在混合宏“border-radius”中定義了一個(gè)不帶任何值的參數(shù)“$radius”。
在調(diào)用的時(shí)候可以給這個(gè)混合宏傳一個(gè)參數(shù)值:
.box {
@include border-radius(3px);
}
這里表示給混合宏傳遞了一個(gè)“border-radius”的值為“3px”。
編譯出來(lái)的 CSS:
.box {
-webkit-border-radius: 3px;
border-radius: 3px;
}
混合宏的參數(shù)--傳一個(gè)帶值的參數(shù)
在 Sass 的混合宏中,還可以給混合宏的參數(shù)傳一個(gè)默認(rèn)值,例如:
@mixin border-radius($radius:3px){
-webkit-border-radius: $radius;
border-radius: $radius;
}
在混合宏“border-radius”傳了一個(gè)參數(shù)“$radius”,而且給這個(gè)參數(shù)賦予了一個(gè)默認(rèn)值“3px”。
在調(diào)用類似這樣的混合宏時(shí),會(huì)多有一個(gè)機(jī)會(huì),假設(shè)你的頁(yè)面中的圓角很多地方都是“3px”的圓角,那么這個(gè)時(shí)候只需要調(diào)用默認(rèn)的混合宏“border-radius”:
.btn {
@include border-radius;
}
編譯出來(lái)的 CSS:
.btn {
-webkit-border-radius: 3px;
border-radius: 3px;
}
但有的時(shí)候,頁(yè)面中有些元素的圓角值不一樣,那么可以隨機(jī)給混合宏傳值,如:
.box {
@include border-radius(50%);
}
編譯出來(lái)的 CSS:
.box {
-webkit-border-radius: 50%;
border-radius: 50%;
}
混合宏的參數(shù)--傳多個(gè)參數(shù)
Sass 混合宏除了能傳一個(gè)參數(shù)之外,還可以傳多個(gè)參數(shù),如:
@mixin center($width,$height){
width: $width;
height: $height;
position: absolute;
top: 50%;
left: 50%;
margin-top: -($height) / 2;
margin-left: -($width) / 2;
}
在混合宏“center”就傳了多個(gè)參數(shù)。在實(shí)際調(diào)用和其調(diào)用其他混合宏是一樣的:
.box-center {
@include center(500px,300px);
}
編譯出來(lái) CSS:
.box-center {
width: 500px;
height: 300px;
position: absolute;
top: 50%;
left: 50%;
margin-top: -150px;
margin-left: -250px;
}
有一個(gè)特別的參數(shù)“…”。當(dāng)混合宏傳的參數(shù)過(guò)多之時(shí),可以使用參數(shù)來(lái)替代,如:
@mixin box-shadow($shadows...){
@if length($shadows) >= 1 {
-webkit-box-shadow: $shadows;
box-shadow: $shadows;
} @else {
$shadows: 0 0 2px rgba(#000,.25);
-webkit-box-shadow: $shadow;
box-shadow: $shadow;
}
}
在實(shí)際調(diào)用中:
.box {
@include box-shadow(0 0 1px rgba(#000,.5),0 0 2px rgba(#000,.2));
編譯出來(lái)的CSS:
.box {
-webkit-box-shadow: 0 0 1px rgba(0, 0, 0, 0.5), 0 0 2px rgba(0, 0, 0, 0.2);
box-shadow: 0 0 1px rgba(0, 0, 0, 0.5), 0 0 2px rgba(0, 0, 0, 0.2);
}
混合宏的參數(shù)--混合宏的不足
混合宏在實(shí)際編碼中給我們帶來(lái)很多方便之處,特別是對(duì)于復(fù)用重復(fù)代碼塊。但其最大的不足之處是會(huì)生成冗余的代碼塊。比如在不同的地方調(diào)用一個(gè)相同的混合宏時(shí)。如:
@mixin border-radius{
-webkit-border-radius: 3px;
border-radius: 3px;
}
.box {
@include border-radius;
margin-bottom: 5px;
}
.btn {
@include border-radius;
}
示例在“.box”和“.btn”中都調(diào)用了定義好的“border-radius”混合宏。先來(lái)看編譯出來(lái)的 CSS:
.box {
-webkit-border-radius: 3px;
border-radius: 3px;
margin-bottom: 5px;
}
.btn {
-webkit-border-radius: 3px;
border-radius: 3px;
}
上例明顯可以看出,Sass 在調(diào)用相同的混合宏時(shí),并不能智能的將相同的樣式代碼塊合并在一起。這也是 Sass 的混合宏最不足之處。
擴(kuò)展/繼承
繼承對(duì)于了解 CSS 的同學(xué)來(lái)說(shuō)一點(diǎn)都不陌生,先來(lái)看一張圖:
圖中代碼顯示“.col-sub .block li,.col-extra .block li” 繼承了 “.item-list ul li”選擇器的 “padding : 0;” 和 “ul li” 選擇器中的 “l(fā)ist-style : none outside none;”以及 * 選擇器中的 “box-sizing:inherit;”。
在 Sass 中也具有繼承一說(shuō),也是繼承類中的樣式代碼塊。在 Sass 中是通過(guò)關(guān)鍵詞 “@extend”來(lái)繼承已存在的類樣式塊,從而實(shí)現(xiàn)代碼的繼承。如下所示:
//SCSS
.btn {
border: 1px solid #ccc;
padding: 6px 10px;
font-size: 14px;
}
.btn-primary {
background-color: #f36;
color: #fff;
@extend .btn;
}
.btn-second {
background-color: orange;
color: #fff;
@extend .btn;
}
編譯出來(lái)之后:
//CSS
.btn, .btn-primary, .btn-second {
border: 1px solid #ccc;
padding: 6px 10px;
font-size: 14px;
}
.btn-primary {
background-color: #f36;
color: #fff;
}
.btn-second {
background-clor: orange;
color: #fff;
}
從示例代碼可以看出,在 Sass 中的繼承,可以繼承類樣式塊中所有樣式代碼,而且編譯出來(lái)的 CSS 會(huì)將選擇器合并在一起,形成組合選擇器:
.btn, .btn-primary, .btn-second {
border: 1px solid #ccc;
padding: 6px 10px;
font-size: 14px;
}
占位符 %placeholder
Sass 中的占位符 %placeholder 功能是一個(gè)很強(qiáng)大,很實(shí)用的一個(gè)功能,這也是我非常喜歡的功能。他可以取代以前 CSS 中的基類造成的代碼冗余的情形。因?yàn)?%placeholder 聲明的代碼,如果不被 @extend 調(diào)用的話,不會(huì)產(chǎn)生任何代碼。來(lái)看一個(gè)演示:
%mt5 {
margin-top: 5px;
}
%pt5{
padding-top: 5px;
}
這段代碼沒(méi)有被 @extend 調(diào)用,他并沒(méi)有產(chǎn)生任何代碼塊,只是靜靜的躺在你的某個(gè) SCSS 文件中。只有通過(guò) @extend 調(diào)用才會(huì)產(chǎn)生代碼:
//SCSS
%mt5 {
margin-top: 5px;
}
%pt5{
padding-top: 5px;
}
.btn {
@extend %mt5;
@extend %pt5;
}
.block {
@extend %mt5;
span {
@extend %pt5;
}
}
編譯出來(lái)的CSS:
//CSS
.btn, .block {
margin-top: 5px;
}
.btn, .block span {
padding-top: 5px;
}
從編譯出來(lái)的 CSS 代碼可以看出,通過(guò) @extend 調(diào)用的占位符,編譯出來(lái)的代碼會(huì)將相同的代碼合并在一起。這也是我們希望看到的效果,也讓你的代碼變得更為干凈。
混合宏 VS 繼承 VS 占位符
初學(xué)者都常常糾結(jié)于這個(gè)問(wèn)題“什么時(shí)候用混合宏,什么時(shí)候用繼承,什么時(shí)候使用占位符?”其實(shí)他們各有各的優(yōu)點(diǎn)與缺點(diǎn),先來(lái)看看他們使用效果:
//SCSS中混合宏使用
@mixin mt($var){
margin-top: $var;
}
.block {
@include mt(5px);
span {
display:block;
@include mt(5px);
}
}
.header {
color: orange;
@include mt(5px);
span{
display:block;
@include mt(5px);
}
}
//SCSS 繼承的運(yùn)用
.mt{
margin-top: 5px;
}
.block {
@extend .mt;
span {
display:block;
@extend .mt;
}
}
.header {
color: orange;
@extend .mt;
span{
display:block;
@extend .mt;
}
}
//SCSS中占位符的使用
%mt{
margin-top: 5px;
}
.block {
@extend %mt;
span {
display:block;
@extend %mt;
}
}
.header {
color: orange;
@extend %mt;
span{
display:block;
@extend %mt;
}
}
a) Sass 中的混合宏使用
舉例代碼見(jiàn)上面 2-24 行
.block {
margin-top: 5px; }
.block span {
display: block;
margin-top: 5px; }
.header {
color: orange;
margin-top: 5px; }
.header span {
display: block;
margin-top: 5px; }
總結(jié):編譯出來(lái)的 CSS 清晰告訴了大家,他不會(huì)自動(dòng)合并相同的樣式代碼,如果在樣式文件中調(diào)用同一個(gè)混合宏,會(huì)產(chǎn)生多個(gè)對(duì)應(yīng)的樣式代碼,造成代碼的冗余,這也是 CSSer 無(wú)法忍受的一件事情。不過(guò)他并不是一無(wú)事處,他可以傳參數(shù)。
個(gè)人建議:如果你的代碼塊中涉及到變量,建議使用混合宏來(lái)創(chuàng)建相同的代碼塊。
b) Sass 中繼承
同樣的,將上面代碼中的混合宏,使用類名來(lái)表示,然后通過(guò)繼承來(lái)調(diào)用:
代碼見(jiàn)右側(cè) 26-48 行
.mt, .block, .block span, .header, .header span {
margin-top: 5px; }
.block span {
display: block; }
.header {
color: orange; }
.header span {
display: block; }
總結(jié):使用繼承后,編譯出來(lái)的 CSS 會(huì)將使用繼承的代碼塊合并到一起,通過(guò)組合選擇器的方式向大家展現(xiàn),比如 .mt, .block, .block span, .header, .header span。這樣編譯出來(lái)的代碼相對(duì)于混合宏來(lái)說(shuō)要干凈的多,也是 CSSer 期望看到。但是他不能傳變量參數(shù)。
個(gè)人建議:如果你的代碼塊不需要專任何變量參數(shù),而且有一個(gè)基類已在文件中存在,那么建議使用 Sass 的繼承。
c) 占位符
最后來(lái)看占位符,將上面代碼中的基類 .mt 換成 Sass 的占位符格式:
代碼見(jiàn) 50-72 行
.block, .block span, .header, .header span {
margin-top: 5px; }
.block span {
display: block; }
.header {
color: orange; }
.header span {
display: block; }
總結(jié):編譯出來(lái)的 CSS 代碼和使用繼承基本上是相同,只是不會(huì)在代碼中生成占位符 mt 的選擇器。那么占位符和繼承的主要區(qū)別的,“占位符是獨(dú)立定義,不調(diào)用的時(shí)候是不會(huì)在 CSS 中產(chǎn)生任何代碼;繼承是首先有一個(gè)基類存在,不管調(diào)用與不調(diào)用,基類的樣式都將會(huì)出現(xiàn)在編譯出來(lái)的 CSS 代碼中。”
來(lái)看一個(gè)表格,關(guān)系說(shuō)明圖:
插值#{}
使用 CSS 預(yù)處理器語(yǔ)言的一個(gè)主要原因是想使用 Sass 獲得一個(gè)更好的結(jié)構(gòu)體系。比如說(shuō)你想寫(xiě)更干凈的、高效的和面向?qū)ο蟮?CSS。Sass 中的插值(Interpolation)就是重要的一部分。讓我們看一下下面的例子:
$properties: (margin, padding);
@mixin set-value($side, $value) {
@each $prop in $properties {
#{$prop}-#{$side}: $value;
}
}
.login-box {
@include set-value(top, 14px);
}
@each...in...語(yǔ)句會(huì)在《Sass進(jìn)級(jí)篇》中 1-6 @each循環(huán) 中講解。
它可以讓變量和屬性工作的很完美,上面的代碼編譯成 CSS:
.login-box {
margin-top: 14px;
padding-top: 14px;
}
這是 Sass 插值中一個(gè)簡(jiǎn)單的實(shí)例。當(dāng)你想設(shè)置屬性值的時(shí)候你可以使用字符串插入進(jìn)來(lái)。另一個(gè)有用的用法是構(gòu)建一個(gè)選擇器。可以這樣使用:
@mixin generate-sizes($class, $small, $medium, $big) {
.#{$class}-small { font-size: $small; }
.#{$class}-medium { font-size: $medium; }
.#{$class}-big { font-size: $big; }
}
@include generate-sizes("header-text", 12px, 20px, 40px);
編譯出來(lái)的 CSS:
ader-text-small { font-size: 12px; }
.header-text-medium { font-size: 20px; }
.header-text-big { font-size: 40px; }
一旦你發(fā)現(xiàn)這一點(diǎn),你就會(huì)想到超級(jí)酷的 mixins,用來(lái)生成代碼或者生成另一個(gè) mixins。然而,這并不完全是可能的。第一個(gè)限制,這可能會(huì)很刪除用于 Sass 變量的插值:
$margin-big: 40px;
$margin-medium: 20px;
$margin-small: 12px;
@mixin set-value($size) {
margin-top: $margin-#{$size};
}
.login-box {
@include set-value(big);
}
上面的 Sass 代碼編譯出來(lái),你會(huì)得到下面的信息:
error style.scss (Line 5: Undefined variable: “$margin-".)
所以,#{}語(yǔ)法并不是隨處可用,你也不能在 mixin 中調(diào)用:
@mixin updated-status {
margin-top: 20px;
background: #F00;
}
$flag: "status";
.navigation {
@include updated-#{$flag};
}
上面的代碼在編譯成 CSS 時(shí)同樣會(huì)報(bào)錯(cuò):
error style.scss (Line 7: Invalid CSS after "...nclude updated-": expected "}", was "#{$flag};")
幸運(yùn)的是,可以使用 @extend 中使用插值。例如:
%updated-status {
margin-top: 20px;
background: #F00;
}
.selected-status {
font-weight: bold;
}
$flag: "status";
.navigation {
@extend %updated-#{$flag};
@extend .selected-#{$flag};
}
上面的 Sass 代碼是可以運(yùn)行的,因?yàn)樗o了我們力量,可以動(dòng)態(tài)的插入 .class 和 %placeholder。當(dāng)然他們不能接受像 mixin 這樣的參數(shù),上面的代碼編譯出來(lái)的 CSS:
.navigation {
margin-top: 20px;
background: #F00;
}
.selected-status, .navigation {
font-weight: bold;
}
注釋
注釋對(duì)于一名程序員來(lái)說(shuō),是極其重要,良好的注釋能幫助自己或者別人閱讀源碼。在 Sass 中注釋有兩種方式,我暫且將其命名為:
1、類似 CSS 的注釋方式,使用 ”/* ”開(kāi)頭,結(jié)屬使用 ”*/ ”
2、類似 JavaScript 的注釋方式,使用“//”
兩者區(qū)別,前者會(huì)在編譯出來(lái)的 CSS 顯示,后者在編譯出來(lái)的 CSS 中不會(huì)顯示,來(lái)看一個(gè)示例:
//定義一個(gè)占位符
%mt5 {
margin-top: 5px;
}
/*調(diào)用一個(gè)占位符*/
.box {
@extend %mt5;
}
編譯出來(lái)的css:
.box {
margin-top: 5px;
}
/*調(diào)用一個(gè)占位符*/
數(shù)據(jù)類型
Sass 和 JavaScript 語(yǔ)言類似,也具有自己的數(shù)據(jù)類型,在 Sass 中包含以下幾種數(shù)據(jù)類型:
- 數(shù)字: 如,1、 2、 13、 10px;
- 字符串:有引號(hào)字符串或無(wú)引號(hào)字符串,如,"foo"、 'bar'、 baz;
- 顏色:如,blue、 #04a3f9、 rgba(255,0,0,0.5);
- 布爾型:如,true、 false;
- 空值:如,null;
- 值列表:用空格或者逗號(hào)分開(kāi),如,1.5em 1em 0 2em 、 Helvetica, Arial, sans-serif。
SassScript 也支持其他 CSS 屬性值(property value),比如 Unicode 范圍,或 !important 聲明。然而,Sass 不會(huì)特殊對(duì)待這些屬性值,一律視為無(wú)引號(hào)字符串 (unquoted strings)。
后兩個(gè)小節(jié)詳細(xì)講解字符串和值列表數(shù)據(jù)類型,其它類型與JavaScript中的用法一致。
字符串
SassScript 支持 CSS 的兩種字符串類型:
- 有引號(hào)字符串 (quoted strings),如 "Lucida Grande" 、'http://sass-lang.com';
- 無(wú)引號(hào)字符串 (unquoted strings),如 sans-serifbold。
在編譯 CSS 文件時(shí)不會(huì)改變其類型。只有一種情況例外,使用 #{ }插值語(yǔ)句 (interpolation) 時(shí),有引號(hào)字符串將被編譯為無(wú)引號(hào)字符串,這樣方便了在混合指令 (mixin) 中引用選擇器名。
@mixin firefox-message($selector) {
body.firefox #{$selector}:before {
content: "Hi, Firefox users!";
}
}
@include firefox-message(".header");
編譯為:
body.firefox .header:before {
content: "Hi, Firefox users!"; }
需要注意的是:當(dāng) deprecated = property syntax 時(shí) (暫時(shí)不理解是怎樣的情況),所有的字符串都將被編譯為無(wú)引號(hào)字符串,不論是否使用了引號(hào)。
值列表
所謂值列表 (lists) 是指 Sass 如何處理 CSS 中:
margin: 10px 15px 0 0
或者:
font-face: Helvetica, Arial, sans-serif
像上面這樣通過(guò)空格或者逗號(hào)分隔的一系列的值。
事實(shí)上,獨(dú)立的值也被視為值列表——只包含一個(gè)值的值列表。
Sass列表函數(shù)(Sass list functions)賦予了值列表更多功能(Sass進(jìn)級(jí)會(huì)有講解):
- nth函數(shù)(nth function) 可以直接訪問(wèn)值列表中的某一項(xiàng);
- join函數(shù)(join function) 可以將多個(gè)值列表連結(jié)在一起;
- append函數(shù)(append function) 可以在值列表中添加值;
- @each規(guī)則(@each rule) 則能夠給值列表中的每個(gè)項(xiàng)目添加樣式。
值列表中可以再包含值列表,比如 1px 2px, 5px 6px 是包含 1px 2px 與 5px 6px 兩個(gè)值列表的值列表。如果內(nèi)外兩層值列表使用相同的分隔方式,要用圓括號(hào)包裹內(nèi)層,所以也可以寫(xiě)成 (1px 2px) (5px 6px)。當(dāng)值列表被編譯為 CSS 時(shí),Sass 不會(huì)添加任何圓括號(hào),因?yàn)?CSS 不允許這樣做。(1px 2px) (5px 6px)與 1px 2px 5px 6px 在編譯后的 CSS 文件中是一樣的,但是它們?cè)?Sass 文件中卻有不同的意義,前者是包含兩個(gè)值列表的值列表,而后者是包含四個(gè)值的值列表。
可以用 () 表示空的列表,這樣不可以直接編譯成 CSS,比如編譯 font-family: ()時(shí),Sass 將會(huì)報(bào)錯(cuò)。如果值列表中包含空的值列表或空值,編譯時(shí)將清除空值,比如 1px 2px () 3px 或 1px 2px null 3px。