Sass 控制指令
1. 前言
Sass 為我們提供了很多控制指令,使得我們可以更高效的來控制樣式的輸出,或者在函數(shù)中進(jìn)行邏輯控制。本節(jié)內(nèi)容我們就來講解什么是 Sass 控制指令?它能用來做什么?它將使你更方便的編寫 Sass 。
2. 什么是 Sass 控制指令
控制指令,故名思義它是通過條件來控制某些邏輯的,提到條件你首先肯定想到了 if ,沒錯這是 Sass 控制指令的一種,除了這個還有循環(huán),所以 Sass 一共為我們提供了 4 種控制指令,它們分別是:
- @if 指令
- @each 指令
- @for 指令
- @while 指令
如果你熟悉其他的編程語言或者你熟悉 javascript ,看見上面這四種是不是很熟悉,它們在 Sass 中也是用來做條件判斷和循環(huán)的,下面我們就看一下它們?nèi)绾卧?Sass 中應(yīng)用。
3. 語法詳情
一般控制指令都是應(yīng)用于函數(shù)或 @mixin 中,我們舉一個在函數(shù)中應(yīng)用的例子來感受下:
// 判斷class長度范圍
@function classLong($class, $max) {
$leng: str-length($class);
@if $leng > $max {
@return true;
} @else {
@return false;
}
}
可以看到上面的代碼中我們用到了 @if 指令,下面我們來詳細(xì)的講解這四種控制指令。
3.1 @if 指令
@if 指令是在 @if 后跟一個表達(dá)式,然后再接 {} ,如果表達(dá)式為 true 則執(zhí)行 {} 里的代碼邏輯,寫為 @if { … } ,我們來舉例看下:
@mixin avatar($size, $circle: false) {
height: $size;
@if $circle {
width: $size / 2;
}
}
.square { @include avatar(100px, $circle: true); }
上面我們在 @mixin 中使用了 @if 指令,如果 @if 后面的表達(dá)式或變量為 true ,它將執(zhí)行 {} 里的代碼。上面的代碼在 .square 的樣式中使用了 @mixin ,它將會生成如下的 CSS 代碼:
.square {
height: 100px;
width: 50px;
}
從上面兩段代碼的對比中我們看到,我們?yōu)?@mixin 傳入了 $size 并且 @if 后面的變量為 true,所以它執(zhí)行了 width: $size / 2 生成的 CSS 就是 width: 50px ,在這里你要重點關(guān)注 @if 指令的用法,關(guān)于 @mixin 在后面的章節(jié)我們會詳細(xì)講到,這里你可以先認(rèn)識下就好。
3.1.1 @else 和 @else if 指令
如果你了解任何的編程語言,那么你一定知道有 if 就會有 else 和 else if ,如果 @if 后面的表達(dá)式為 false ,就會判斷 @else if 后面的表達(dá)式,如果還是 false 則會繼續(xù)往后走,如果所有表達(dá)式都為 false 則最終會執(zhí)行 @else 后面的 {} 中的代碼邏輯。
當(dāng)然 @else if 和 @else是在你需要多條邏輯判斷的時候?qū)懙模部梢圆粚?,就像上面的代碼一樣。說了這么多可能你不是很理解,一碼勝千言,我們直接將上面的代碼段改造下,實際體會一下:
@mixin avatar($size, $circle: 1) {
height: $size;
@if $circle == 1 {
width: $size / 2;
} @else if $circle == 2 {
width: $size / 5;
} @else {
width: $size;
}
}
.a { @include avatar(100px); }
.b { @include avatar(100px, $circle: 2); }
.c { @include avatar(100px, $circle: 3); }
上面的代碼中我有 3 條判斷邏輯對應(yīng)不同的代碼塊,然后我在 .a .b .c 中分別調(diào)用 @mixin 并傳入不同的參數(shù),轉(zhuǎn)換后的 CSS 代碼如下:
.a {
height: 100px;
width: 50px;
}
.b {
height: 100px;
width: 20px;
}
.c {
height: 100px;
width: 100px;
}
通過上面的講解可以看到 @if 指令還是非常實用的,在你寫函數(shù)的時候很多地方會用到,所以這塊要好好記住。
3.2 @each 指令
@each 指令一般用來循環(huán)一個列表或 Map ,它的寫法是這樣的 @each in { … } ,這其中 expression 表達(dá)式返回一個列表或者直接就是一個列表,variable 是列表中的每一項,{} 中是每次循環(huán)都會執(zhí)行的代碼,我們舉例來看下:
$borders: 2px, 3px, 5px;
@each $bor in $borders {
.border-#{$bor} {
border:$bor solid;
}
}
上面的代碼中我們通過 @each 循環(huán)一個 $borders 列表,來生成不同的 class 的 border 樣式,上面這段代碼轉(zhuǎn)換為 CSS 如下:
.border-2px {
border: 2px solid;
}
.border-3px {
border: 3px solid;
}
.border-5px {
border: 5px solid;
}
可以看到上面的寫法是不是很方便,這樣就直接生成了不用的類名并且對應(yīng)不同的樣式,在 Sass 編程中 @each 也是很常用的指令,所以這個你是一定要會用的,尤其是在寫函數(shù)的時候!
3.3 @for 指令
@for 指令很有意思,它可以設(shè)定一個范圍然后在這個范圍內(nèi)循環(huán),比如說在 1 ~ 5 這個范圍內(nèi),或者在 3 ~ 6 這個范圍內(nèi)等等。
它有兩種寫法 @for from to { … } 或者 @for from through { … },這兩種寫法中variable 都是每次循環(huán)時候的數(shù)值,start 都表示開始的邊界,end 都表示結(jié)束的邊界;
這兩種寫法不同的是 through 包含 start 與 en ,而 to 包含 start 但不包含 end。文字描述難免有些抽象,我們直接舉例看下:
$base-color: #036;
// 范圍是 1 ~ 3
@for $i from 1 through 3 {
ul:nth-child(3n + #{$i}) {
background-color: lighten($base-color, $i * 5%);
}
}
// 范圍是 4 ~ 6
@for $i from 4 through 6 {
ul:nth-child(3n + #{$i}) {
background-color: lighten($base-color, $i * 5%);
}
}
上面的代碼我們用的是 through 寫法,分別寫了 1 ~ 3 范圍的循環(huán)和 4 ~ 6范圍的循環(huán),也就是說循環(huán)體中的代碼塊會分別被計算 3 次,它最終會轉(zhuǎn)換為如下的 CSS 代碼:
// 1 ~ 3 范圍生成的
ul:nth-child(3n+1) {
background-color: #004080;
}
ul:nth-child(3n+2) {
background-color: #004d99;
}
ul:nth-child(3n+3) {
background-color: #0059b3;
}
// 4 ~ 6 范圍生成的
ul:nth-child(3n+4) {
background-color: #0066cc;
}
ul:nth-child(3n+5) {
background-color: #0073e6;
}
ul:nth-child(3n+6) {
background-color: #0080ff;
}
看到轉(zhuǎn)換后的 CSS 是不是感覺使用 @for 指令寫起來簡直飛快,下面我們在使用 to 寫法來舉個例子看下:
$base-color: #036;
@for $i from 1 to 3 {
ul:nth-child(3n + #{$i}) {
background-color: lighten($base-color, $i * 5%);
}
}
上面使用 to 寫法的代碼將會轉(zhuǎn)換為如下的 CSS 代碼:
ul:nth-child(3n+1) {
background-color: #004080;
}
ul:nth-child(3n+2) {
background-color: #004d99;
}
好了,通過上面的代碼可以看出使用 to 寫法是不包含 end 邊界的。從上面我們舉的兩個例子不難看出,@for 指令可以極大的簡化我們編寫冗余繁瑣的 CSS ,你自己需要多嘗試這個指令來實際感受下。
3.4 @while 指令
@while 指令很像 javascript 中的 while 循環(huán),在 Sass 中 @while 指令的寫法是 @while { … } ,當(dāng)表達(dá)式 expression 結(jié)果為 true 時就執(zhí)行 {} 里的代碼,直到表達(dá)式 expression 結(jié)果為 false 。我們舉例來看下:
$num: 4;
@while $num >= 1 {
.box-#{$num} {
font-weight: 100 * $num;
}
$num: $num - 1;
}
從上面的代碼可以看出我設(shè)定了一個變量 $num 為 4 ,然后每次循環(huán)將這個變量 -1 ,知道 $num < 1 的時候會停止循環(huán),也就是說會循環(huán) 4 次,我們看下下面轉(zhuǎn)換為 CSS 的代碼:
.box-4 {
font-weight: 400;
}
.box-3 {
font-weight: 300;
}
.box-2 {
font-weight: 200;
}
.box-1 {
font-weight: 100;
}
@while 指令可以讓你很方便的控制循環(huán)次數(shù),在實際應(yīng)用中也是非常有用的!
4. 實戰(zhàn)經(jīng)驗
在實際項目中應(yīng)用 Sass 控制指令的地方還是蠻多的,這里我說一個在我的項目中的應(yīng)用。我的項目中有個需求是將視口分為 12 等份,然后根據(jù)不同的 class 類名來為其寬度設(shè)置不同的百分比,這很像其他 UI 庫中的柵格系統(tǒng),我們是這樣在項目中實現(xiàn)的:
@for $i from 0 through 12 {
.width-#{$i} {
width: (1 / 12 * $i) * 100%;
}
}
上面這幾行代碼就實現(xiàn)了我的需求,我需要有 .width-0 到 .width-12 的選擇器,同時它們的樣式分別是對應(yīng)的百分比,我直接做了一個從 0 到 12 的循環(huán),然后在其循環(huán)體中動態(tài)生成 class 和樣式,它轉(zhuǎn)換為 CSS 代碼如下:
.width-0 {
width: 0%;
}
.width-1 {
width: 8.3333333333%;
}
.width-2 {
width: 16.6666666667%;
}
.width-3 {
width: 25%;
}
.width-4 {
width: 33.3333333333%;
}
.width-5 {
width: 41.6666666667%;
}
.width-6 {
width: 50%;
}
.width-7 {
width: 58.3333333333%;
}
.width-8 {
width: 66.6666666667%;
}
.width-9 {
width: 75%;
}
.width-10 {
width: 83.3333333333%;
}
.width-11 {
width: 91.6666666667%;
}
.width-12 {
width: 100%;
}
從上面這個示例中是不是可以看出使用控制指令來實現(xiàn)一些需求很方便,這樣可以省去你編寫大量 CSS 代碼的工作,而且計算寬度也僅僅需要設(shè)置好公式即可,在我們的項目中有很多類似的用法,至于 @if 指令一般會在函數(shù)中做判斷來使用。
5. 小結(jié)
本節(jié)內(nèi)容我們講解了 Sass 控制指令,它是非常常用的,在 Sass 中有四種控制指令,它們分別是:
- @if 指令
- @each 指令
- @for 指令
- @while 指令
趁熱打鐵,快來回憶一下這幾個指令都是干嘛的:
記住它們并多加練習(xí),控制指令是非常好用的,它可以讓你避免編寫過多冗余的 CSS 代碼,在項目中也很方便維護(hù)??刂浦噶钍窃?Sass 進(jìn)階中必不可少的知識!