CSS預(yù)處理器 —— Sass進(jìn)階篇
參考網(wǎng)址:
- scss官網(wǎng)
- W3Cschool sass教程 https://www.w3cschool.cn/sass/sass_interview_questions.html
? Sass 支持所有的 CSS3 @-Rules,以及 Sass 特有的 “指令”(directives)。這一節(jié)會(huì)詳細(xì)解釋,更多資料請(qǐng)查看 控制指令 (control directives) 與 混合指令 (mixin directives) 兩個(gè)部分。
五、@-Rules 與指令
CSS3 的 @-Rules指令有:
-
@import 規(guī)則:將另一個(gè)樣式表導(dǎo)入當(dāng)前樣式表。
- 它應(yīng)該出現(xiàn)在任何規(guī)則之前的樣式表的開頭,它的值是一個(gè)URL
-
@charset 規(guī)則:指示樣式表使用的字符集。
- @charset規(guī)則必須直接寫在樣式表的開頭,甚至沒有空格
- 該值保存在引號(hào)中,應(yīng)該是標(biāo)準(zhǔn)字符集之一
- @font-face 規(guī)則:用于詳盡地描述在文檔中使用的字體。
- !important 規(guī)則:表示用戶定義的規(guī)則應(yīng)優(yōu)先于作者的樣式表。
| 1. | @import | 它用于導(dǎo)入sass或scss文件。它直接將文件名導(dǎo)入。 |
|---|---|---|
| 2. | @media | 用于將樣式規(guī)則設(shè)置為不同的媒體類型。 |
| 3. | @extend | 它指定并共享選擇器之間的規(guī)則和關(guān)系。 |
| 4. | @at-root | 它被指定為嵌套規(guī)則的集合, 這些規(guī)則可以在文檔的根目錄創(chuàng)建樣式塊。 |
| 5. | @debug | 該偽指令用于檢測(cè)錯(cuò)誤, 并將SassScript表達(dá)式值顯示到標(biāo)準(zhǔn)錯(cuò)誤輸出流。 |
| 6. | @warn | 該指令用于獲取有關(guān)該問題的警告性建議。它將SassScript表達(dá)式值顯示到標(biāo)準(zhǔn)錯(cuò)誤輸出流。 |
| 7. | @error | 此偽指令用于將SassScript表達(dá)式值顯示為致命錯(cuò)誤。 |
5.1 @import 導(dǎo)入
Sass 拓展了 @import 的功能,允許其導(dǎo)入 SCSS 或 Sass 文件。
1. 例外情況
通常,@import 尋找 Sass 文件并將其導(dǎo)入,但在以下情況下,@import 僅作為普通的 CSS 語句,不會(huì)導(dǎo)入任何 Sass 文件。
- 文件拓展名是
.css; - 文件名以
http://開頭; - 文件名是
url(); -
@import包含 media queries。
2. 基礎(chǔ)知識(shí)
Sass 拓展了 @import 的功能:
- 若不存在上面的4種情況,文件的拓展名是
.scss或.sass,則導(dǎo)入成功- 就算沒有指定拓展名,Sass 也會(huì)試著尋找文件名相同,拓展名為
.scss或.sass的文件并將其導(dǎo)入
- 就算沒有指定拓展名,Sass 也會(huì)試著尋找文件名相同,拓展名為
- Sass 允許同時(shí)導(dǎo)入多個(gè)文件,使用逗號(hào)
,進(jìn)行分隔 - 導(dǎo)入文件也可以使用
#{ }插值語句,但只能作用于 CSS 的url()導(dǎo)入方式,而不是通過變量動(dòng)態(tài)導(dǎo)入 Sass 文件 - 被導(dǎo)入的文件將合并編譯到同一個(gè) CSS 文件中
- 被導(dǎo)入的文件中所包含的變量或者混合指令 (mixin) 都可以在導(dǎo)入的文件中使用 —— 變量和mixin可通用
- Sass 在當(dāng)前地址尋找 Sass 文件
- 如果需要設(shè)定其他地址,可以用
:load_paths選項(xiàng),或者在命令行中輸入--load-path命令
- 如果需要設(shè)定其他地址,可以用
/** 4種情況 @import僅作為普通的 CSS 語句 */
@import "foo.css"; // 文件拓展名是 .css
@import "foo" screen; // @import 包含 media queries
@import "http://foo.com/bar"; // 文件名以 http:// 開頭
@import url(foo); // 文件名是 url()
/** 正確示例 */
@import "foo.scss"; // 文件的拓展名是 .scss 或 .sass
@import "foo"; // 沒有擴(kuò)展名,Sass會(huì)試著找 foo.scss 或者 foo.sass 進(jìn)行導(dǎo)入
@import "rounded-corners", "text-shadow"; // 同時(shí)導(dǎo)入多個(gè)文件,使用逗號(hào)進(jìn)行分隔
/** 使用插值語句 -- 只能作用域 CSS 的 url() 導(dǎo)入方式*/
$family: unquote("Droid+Sans"); // 字符串內(nèi)置函數(shù)unquote(str)去除引號(hào)
@import url("http://fonts.googleapis.com/css?family=\#{$family}"); // CSS url()方式導(dǎo)入
// 編譯結(jié)果: @import url("http://fonts.googleapis.com/css?family=Droid+Sans");
3. 局部 (Partials)
? 如果需要導(dǎo)入 SCSS 或者 Sass 文件,但又不希望將其編譯為 CSS,只需要在文件名前添加下劃線,這樣會(huì)告訴 Sass 不要編譯這些文件,但導(dǎo)入語句中卻不需要添加下劃線。
—— 需要導(dǎo)入 + 不希望被編譯 ---- 將文件命名時(shí),前面加上下劃線。
—— 如:文件名為 _colors.scss; 導(dǎo)入 @import colors.scss; 其實(shí)導(dǎo)入的就是 _colors.scss文件
—— 注意:不可存在同名文件,即不能再有 colors.scss 文件 ---- 因?yàn)閷?dǎo)入語句中不需要添加下劃線
注意,不可以同時(shí)存在添加下劃線與未添加下劃線的同名文件,添加下劃線的文件將會(huì)被忽略。
4. 嵌套 @import
大多數(shù)情況下,一般在文件的最外層(不在嵌套規(guī)則內(nèi))使用 @import,其實(shí),也可以將 @import 嵌套進(jìn) CSS 樣式或者 @media 中,與平時(shí)的用法效果相同,只是這樣導(dǎo)入的樣式只能出現(xiàn)在嵌套的層中。
可以理解成作用域:
- 在文件最外層使用 @import ---- 導(dǎo)入的樣式、變量、mixin等全局可用 ---- 全局
- 在嵌套規(guī)則內(nèi),或者@media中 ---- 導(dǎo)入的樣式只能出現(xiàn)在嵌套的層中 ---- 局部
注意: 不可以在混合指令 (mixin) 或控制指令 (control directives) 中嵌套 @import
// example.scss
.example {
color: red;
}
// index.scss
#main {
@import "example"; // 導(dǎo)入到 #main 樣式內(nèi)
}
// 編譯結(jié)果
#main .example {
color: red;
}
5. 與原生CSS中的@import的區(qū)別
- 原生CSS的@import命令有一個(gè)缺陷,它會(huì)造成多次HTTP請(qǐng)求,導(dǎo)致效率低下因?yàn)槭窃诮馕鰣?zhí)行CSS代碼遇到此命令的時(shí)候,才會(huì)去下載此命名引入的文件,很明顯這不夠優(yōu)化,所以在實(shí)際應(yīng)用中并不推薦使用
- SCSS中不用擔(dān)心上述問題,它雖然與CSS終使用方式比較類似,但是最終SCSS要編譯成一個(gè)目標(biāo)CSS文件,被引入的SCSS文件中的CSS代碼會(huì)被合并到目標(biāo)CSS文件中,所以不會(huì)產(chǎn)生一次額外的請(qǐng)求
- SCSS可刪減無用css文件 ---- 分音 partials
- SCSS還可以在規(guī)則塊內(nèi)導(dǎo)入外部文件 ----- 嵌套
5.2 @media 媒體查詢
? CSS中的 @media 規(guī)則指定一組規(guī)則的目標(biāo)媒體類型(以逗號(hào)分隔)
? Sass 中 @media 指令與 CSS 中用法一樣,只是增加了一點(diǎn)額外的功能:允許其在 CSS 規(guī)則中嵌套。如果 @media 嵌套在 CSS 規(guī)則內(nèi),編譯時(shí),@media 將被編譯到文件的最外層,包含嵌套的父選擇器。這個(gè)功能讓 @media 用起來更方便,不需要重復(fù)使用選擇器,也不會(huì)打亂 CSS 的書寫流程。
.sidebar {
width: 300px;
@media screen and (orientation: landscape) { // @media嵌套在 CSS 規(guī)則內(nèi)
width: 500px;
}
}
// 編譯后
.sidebar { width: 300px; }
@media screen and (orientation: landscape) { // 編譯時(shí),@media被編譯到文件的最外層
.sidebar { width: 500px; }
}
@media 的 queries 允許互相嵌套使用,編譯時(shí),Sass 自動(dòng)添加 and
@media screen {
.sidebar {
@media (orientation: landscape) { // 嵌套使用
width: 500px;
}
}
}
// 編譯后 --- sass自動(dòng)添加 and 進(jìn)行拼接
@media screen and (orientation: landscape) {
.sidebar { width: 500px; }
}
@media 甚至可以使用 SassScript(比如變量,函數(shù),以及運(yùn)算符)代替條件的名稱或者值
$media: screen;
$feature: -webkit-min-device-pixel-ratio;
$value: 1.5;
// 使用變量
// 可參考插值一章:如果@media后面直接跟變量,就需要用插值語句; 如果跟著圓括號(hào),則不需要用插值語句
@media #{$media} and ($feature: $value) {
.sidebar {
width: 500px;
}
}
// 編譯后
@media screen and (-webkit-min-device-pixel-ratio: 1.5) {
.sidebar { width: 500px; }
}
5.3 @extend 繼承/擴(kuò)展
? 情形:一個(gè)元素使用的樣式與另一個(gè)元素完全相同,但又添加了額外的樣式。
? 通常做法:在 HTML 中給元素定義兩個(gè) class,一個(gè)通用樣式,一個(gè)特殊樣式。
? 不便之處:必須時(shí)刻記住特殊樣式需要參考通用樣式
比如,現(xiàn)在要設(shè)計(jì)一個(gè)普通錯(cuò)誤樣式與一個(gè)嚴(yán)重錯(cuò)誤樣式,一般會(huì)這樣寫:
// <div class="error seriousError"> Oh no! You've been hacked! </div>
.error {
border: 1px #f00;
background-color: #fdd;
}
.seriousError {
border-width: 3px;
}
? 麻煩的是,這樣做必須時(shí)刻記住使用 .seriousError 時(shí)需要參考 .error 的樣式,帶來了很多不變:智能比如加重維護(hù)負(fù)擔(dān),導(dǎo)致 bug,或者給 HTML 添加無語意的樣式。使用 @extend 可以避免上述情況,告訴 Sass 將一個(gè)選擇器下的所有樣式繼承給另一個(gè)選擇器。
.error {
border: 1px #f00;
background-color: #fdd;
}
.error.intrusion { // **其他使用到 `.error` 的樣式也會(huì)同樣繼承給 `.seriousError`**
background-image: url("/image/hacked.png");
}
.seriousError {
@extend .error; // 使用 @extend 繼承.error的所有樣式
border-width: 3px; // 單獨(dú)給 .seriousError 設(shè)定特殊樣式
}
// 編譯后
.error, .seriousError {border: 1px #f00;background-color: #fdd;}
.error.intrusion, .seriousError.intrusion {background-image: url("/image/hacked.png");}
.seriousError {border-width: 3px;}
這樣,使用 .seriousError 的地方可以不再使用 .error。
其他使用到 .error 的樣式也會(huì)同樣繼承給 .seriousError,例如,另一個(gè)樣式 .error.intrusion 使用了 hacked.png 做背景,`` 也同樣會(huì)使用 hacked.png 背景。
1. How it Works
@extend 的作用是將重復(fù)使用的樣式 (.error) 延伸 (extend) 給需要包含這個(gè)樣式的特殊樣式(.seriousError)
當(dāng)合并選擇器時(shí),@extend 會(huì)很聰明地避免無謂的重復(fù),.seriousError.seriousError 將編譯為 .seriousError,不能匹配任何元素的選擇器(比如 #main#footer )也會(huì)刪除
2. 延伸復(fù)雜的選擇器
Class 選擇器并不是唯一可以被延伸 (extend) 的,Sass 允許延伸任何定義給單個(gè)元素的選擇器,比如 .special.cool,a:hover 或者 a.user[href^="http://"] 等,例如:
.hoverlink {
@extend a:hover; // 所有 a:hover 的樣式將繼承給 .hoverlink,包括其他使用到 a:hover 的樣式
}
a:hover {
text-decoration: underline;
}
.comment a.user:hover {
font-weight: bold;
}
// 編譯結(jié)果
a:hover, .hoverlink { text-decoration: underline; }
.comment a.user:hover, .comment .user.hoverlink { font-weight: bold; }
3. 多重延伸
同一個(gè)選擇器可以延伸給多個(gè)選擇器,它所包含的屬性將繼承給所有被延伸的選擇器
.error {
border: 1px #f00;
background-color: #fdd;
}
.attention {
font-size: 3em;
background-color: #ff0;
}
.seriousError { // 可以寫成 @extend .error, .attention;
@extend .error;
@extend .attention;
border-width: 3px;
}
// 編譯結(jié)果
.error, .seriousError { border: 1px #f00; background-color: #fdd; }
.attention, .seriousError { font-size: 3em; background-color: #ff0; }
.seriousError { border-width: 3px; }
? 每個(gè) .seriousError 將包含 .error 與 .attention 下的所有樣式,這時(shí),后定義的樣式享有優(yōu)先權(quán):.seriousError 的背景顏色是 #ff0 而不是 #fdd,因?yàn)?.attention 在 .error 之后定義。
? 多重延伸可以使用逗號(hào)分隔選擇器名,比如 @extend .error, .attention; 與 @extend .error; @extend.attention 有相同的效果。
4. 繼續(xù)延伸
當(dāng)一個(gè)選擇器延伸給第二個(gè)后,可以繼續(xù)將第二個(gè)選擇器延伸給第三個(gè),例如:
.error {
border: 1px #f00;
background-color: #fdd;
}
.seriousError {
@extend .error; // 將.error的所有樣式延伸給.seriousError
border-width: 3px;
}
.criticalError {
@extend .seriousError; // 將.seriousError的所有樣式延伸給.criticalError
color: #fff;
}
// 編譯結(jié)果
.error, .seriousError, .criticalError { border: 1px #f00; background-color: #fdd; }
.seriousError, .criticalError { border-width: 3px; }
.criticalError { color: #fff; }
? 每個(gè) .seriousError 選擇器將包含 .error 的樣式,而 .criticalError 不僅包含 .seriousError 的樣式也會(huì)同時(shí)包含 .error 的所有樣式
5. 選擇器列
? 暫時(shí)不可以將選擇器列 (Selector Sequences),比如 .foo .bar 或 .foo + .bar,延伸給其他元素,但是,卻可以將其他元素延伸給選擇器列:
#fake-links .link { // 將 a 的所有樣式繼承選擇器列:#fake-links .link
@extend a;
}
a {
color: blue;
&:hover {
text-decoration: underline;
}
}
// 編譯為
a, #fake-links .link { color: blue; }
a:hover, #fake-links .link:hover { text-decoration: underline; }
5.1. 合并選擇器列
? 有時(shí)會(huì)遇到復(fù)雜的情況,比如選擇器列中的某個(gè)元素需要延伸給另一個(gè)選擇器列,這種情況下,兩個(gè)選擇器列需要合并,比如:
#admin .tabbar a {
font-weight: bold;
}
#demo .overview .fakelink {
@extend a;
}
? 技術(shù)上講能夠生成所有匹配條件的結(jié)果,但是這樣生成的樣式表太復(fù)雜了,上面這個(gè)簡(jiǎn)單的例子就可能有 10 種結(jié)果。所以,Sass 只會(huì)編譯輸出有用的選擇器。
? 當(dāng)兩個(gè)列 (sequence) 合并時(shí),如果沒有包含相同的選擇器,將生成兩個(gè)新選擇器:第一列出現(xiàn)在第二列之前,或者第二列出現(xiàn)在第一列之前:
#admin .tabbar a {
font-weight: bold;
}
#demo .overview .fakelink {
@extend a;
}
// 編譯為
#admin .tabbar a,
#admin .tabbar #demo .overview .fakelink,
#demo .overview #admin .tabbar .fakelink {
font-weight: bold;
}
? 如果兩個(gè)列 (sequence) 包含了相同的選擇器,相同部分將會(huì)合并在一起,其他部分交替輸出。在下面的例子里,兩個(gè)列都包含 #admin,輸出結(jié)果中它們合并在了一起:
#admin .tabbar a {
font-weight: bold;
}
#admin .overview .fakelink {
@extend a;
}
// 編譯為
#admin .tabbar a,
#admin .tabbar .overview .fakelink,
#admin .overview .tabbar .fakelink {
font-weight: bold;
}
6. @extend-Only 選擇器
? 有時(shí),需要定義一套樣式并不是給某個(gè)元素用,而是只通過 @extend 指令使用,尤其是在制作 Sass 樣式庫的時(shí)候,希望 Sass 能夠忽略用不到的樣式。
? 如果使用普通的 CSS 規(guī)則,最后會(huì)編譯出很多用不到的樣式,也容易與其他樣式名沖突,所以,Sass 引入了“占位符選擇器” (placeholder selectors),看起來很像普通的 id 或 class 選擇器,只是 # 或 . 被替換成了 %??梢韵?class 或者 id 選擇器那樣使用,當(dāng)它們單獨(dú)使用時(shí),不會(huì)被編譯到 CSS 文件中。
// This ruleset won't be rendered on its own.
#context a%extreme {
color: blue;
font-weight: bold;
font-size: 2em;
}
占位符選擇器需要通過延伸指令使用,用法與 class 或者 id 選擇器一樣,被延伸后,占位符選擇器本身不會(huì)被編譯。
.notice {
@extend %extreme;
}
// 編譯為
#context a.notice { color: blue; font-weight: bold; font-size: 2em; }
7. !optional 聲明
? 如果 @extend 失敗會(huì)收到錯(cuò)誤提示,比如,這樣寫 a.important {@extend .notice},當(dāng)沒有 .notice 選擇器時(shí),將會(huì)報(bào)錯(cuò),只有 h1.notice 包含 .notice 時(shí)也會(huì)報(bào)錯(cuò),因?yàn)?h1 與 a 沖突,會(huì)生成新的選擇器。
? 如果要求 @extend 不生成新選擇器,可以通過 !optional 聲明達(dá)到這個(gè)目的,例如:
a.important {
@extend .notice !optional;
}
8. 在指令中延伸
? 在指令中使用 @extend 時(shí)(比如在 @media 中)有一些限制:Sass 不可以將 @media 層外的 CSS 規(guī)則延伸給指令層內(nèi)的 CSS,這樣會(huì)生成大量的無用代碼。也就是說,如果在 @media (或者其他 CSS 指令)中使用 @extend,必須延伸給相同指令層中的選擇器。
? 下面的例子是可行的:
@media print {
.error {
border: 1px #f00;
background-color: #fdd;
}
.seriousError {
@extend .error;
border-width: 3px;
}
}
但不可以這樣:
.error {
border: 1px #f00;
background-color: #fdd;
}
@media print {
.seriousError {
// INVALID EXTEND: .error is used outside of the "@media print" directive
@extend .error;
border-width: 3px;
}
}
希望有一天,瀏覽器可以原生支持 @extend 指令,這樣就可以在任何指令中使用延伸功能,不再受限制了。
5.4 @at-root
@at-root指令可以使一個(gè)或多個(gè)規(guī)則被限定輸出在文檔的根層級(jí)上,而不是被嵌套在其父選擇器下。
.parent{
color:red;
@at-root .child { // 使用@at-root 將.child規(guī)則輸出到文檔的根層級(jí)上
color: #fff;
}
}
// 編譯結(jié)果
.parent { color: red; }
.child { color: #fff; } // 由于使用@at-root命令,那么.child就不參與嵌套,直接跳出嵌套
示例2:@at-root 使多個(gè)規(guī)則跳出嵌套
.parent {
background:red;
@at-root {
.child-1 { color: yellow; }
.child-2 { color: red; }
}
}
// 編譯結(jié)果
.parent { background: red; }
.child-1 { color: yellow; }
.child-2 { color: red; }
代碼在默認(rèn)情況下@at-root并不會(huì)使指定的規(guī)則或則選擇器跳出指令,比如@media或者@supports
@media print {
@at-root{
.foo { color: green; }
}
}
// 編譯結(jié)果
@media print {
.foo { color: green; }
}
可以看出@at-root默認(rèn)情況下并不能使規(guī)則或者選擇器跳出指令。
解決方法:和without和with配合使用解決上述問題
1. 搭配without
默認(rèn)@at-root只會(huì)跳出選擇器嵌套,而不能跳出@media或@support指令。
如果要跳出這兩種指令,則需使用@at-root (without: media),@at-root (without: support)。
這個(gè)語法的關(guān)鍵詞有四個(gè):
- .all:表示所有。
- .rule:表示常規(guī)css。
- .media:表示media。
- .support:表示support。
默認(rèn)的@at-root就是@at-root (without: rule)。
@media print {
.parent{
color:#f00;
@at-root .child { color: #0ff; } // child只能夠跳出.parent,但是不能夠跳出@media
}
}
// 編譯結(jié)果
@media print { .parent { color: red; } .child { color: #0ff; } }
@media print {
.parent{
color:red;
@at-root (without: media) { // 指定只跳出media,但并不會(huì)跳出.parent
.child { color: #0ff; }
}
}
}
// 編譯結(jié)果
@media print { .parent { color: red; } }
.parent .child { color: #0ff; }
@media print {
.parent{
color:red;
@at-root (without: all) { // all標(biāo)識(shí)要跳出所有
.child { color: #0ff; }
}
}
}
// 編譯結(jié)果
@media print { .parent { color: red; } }
.child { color: #0ff; }
2. 搭配with
? with 的作用恰好和 without 相反,如果說without作用是指定跳出哪些指令的話,那么with就是指定不跳出哪些指令,其他的指令都跳出
@media print {
@supports ( transform-origin: 5% 5% ) {
@at-root (with: supports){ // 除了supports,其他指令都跳出
.foo { color: green; }
}
}
}
// 編譯結(jié)果
@supports (transform-origin: 5% 5%) { .foo { color: green; } }
5.5 @debug
@debug偽指令檢測(cè)錯(cuò)誤,并將SassScript表達(dá)式值顯示到標(biāo)準(zhǔn)錯(cuò)誤輸出流
$font-sizes: 10px + 20px; // 算術(shù)表達(dá)式
$style: ( // maps類型
color: #bdc3c7
);
.container{
@debug $style;
@debug $font-sizes;
}
// 輸入命令 sass --watch C:\ruby\lib\sass\debug.scss:debug.css

5.6 @warn
Sass @warn指令在出現(xiàn)問題并希望向用戶提供警告性建議時(shí)使用。它將SassScript表達(dá)式的值顯示到標(biāo)準(zhǔn)錯(cuò)誤輸出流。
@warn和@debug之間有兩個(gè)特定的區(qū)別:
- 可以使用–quiet命令行選項(xiàng)或:quiet Sass選項(xiàng)關(guān)閉警告。
- Sass @warn偽指令提供打印輸出以及消息, 以便在警告發(fā)生的地方警告用戶。
示例:讓我們創(chuàng)建一個(gè)名為” warn.scss”的SCSS文件, 其中包含以下數(shù)據(jù)。
$main-color: #bdc3c7;
@warn "Darker: " darken($main-color, 30%);
現(xiàn)在, 打開命令提示符并運(yùn)行watch命令, 以告知SASS監(jiān)視文件并在更改SASS文件時(shí)更新CSS。
執(zhí)行以下代碼:sass –watch warn.scss:warn.css
它將在同一目錄中自動(dòng)創(chuàng)建一個(gè)名為” warn.css”的普通CSS文件。

5.7 @error
@error指令將SassScript表達(dá)式值顯示為致命錯(cuò)誤。
$colors: (
blue: #c0392b,
black: #2980b9,
);
@function style-variation($style) {
@if map-has-key($colors, $style) {
@return map-get($colors, $style);
}
@error "Invalid color: '#{$style}'.";
}
.container {
style: style-variation(white);
}

六、控制指令 (Control Directives)
SassScript 提供了一些基礎(chǔ)的控制指令,比如在滿足一定條件時(shí)引用樣式,或者設(shè)定范圍重復(fù)輸出格式??刂浦噶钍且环N高級(jí)功能,日常編寫過程中并不常用到,主要與混合指令 (mixin) 配合使用,尤其是用在 Compass 等樣式庫中。
if()
語法:
if( expression, value1, value2 )說明:內(nèi)置函數(shù),基于條件expression,如果表達(dá)式結(jié)果為真,則返回 value1;為假則返回 value2。函數(shù)的結(jié)果可以參考可能未被定義的變量或具有進(jìn)一步的計(jì)算。
h2{
color: if( 1 + 1 == 2 , green , red);
}
// 編譯結(jié)果
h2 { color: green; }
@if
當(dāng)
@if的表達(dá)式返回值不是false或者null時(shí),條件成立,輸出{}內(nèi)的代碼@if聲明后面可以跟多個(gè)@else if聲明,或者一個(gè)@else聲明。如果@if聲明失敗,Sass 將逐條執(zhí)行@else if聲明,如果全部失敗,最后執(zhí)行@else聲明
$type: monster;
p {
@if 1 + 1 == 2 { border: 1px solid; } // 表達(dá)式的值是 true -- 真
@if 5 < 3 { border: 2px dotted; } // 表達(dá)式的值是 false -- 假
@if null { border: 3px double; } // 表達(dá)式的值是 null -- 假
@if $type == ocean {
color: blue;
} @else if $type == matador {
color: red;
} @else if $type == monster {
color: green;
} @else {
color: black;
}
}
@for
@for 指令可以在限制的范圍內(nèi)重復(fù)輸出格式,每次按要求(變量的值)對(duì)輸出結(jié)果做出變動(dòng)。
兩種格式:
@for $var from <start> through <end>@for $var from <start> to <end>區(qū)別在于
through與to的含義:
- 當(dāng)使用
through時(shí),條件范圍包含<start>與<end>的值; start <= $val <= end ----- [start, end]- 使用
to時(shí)條件范圍只包含<start>的值不包含<end>的值; start <= $val < end ----- [start, end)
$var可以是任何變量,比如$i;<start>和<end>必須是整數(shù)值
@for $index from 1 through 3 {
.item-#{$index} { width: 2em * $index; }
}
// 編譯結(jié)果
.item-1 { width: 2em; } .item-2 { width: 4em; } .item-3 { width: 6em; }
@each
語法:
@each $var in <list or map>說明:
$var可以是任何變量名,比如$length,$name;?
<list or map>是一連串的值,也就是值列表(數(shù)組、Maps ...)
@each 將變量 $var 作用于值列表中的每一個(gè)項(xiàng)目,然后輸出結(jié)果,例如:
// 聲明變量 $animal 循環(huán)列表: puma, sea-slug, egret, salamander
@each $animal in puma, egret, sea-slug, salamander {
.#{$animal}-icon {
background-image: url('/images/#{$animal}.png');
}
}
// 編譯結(jié)果
.puma-icon { background-image: url('/images/puma.png'); }
.egret-icon { background-image: url('/images/egret.png'); }
.sea-slug-icon { background-image: url('/images/sea-slug.png'); }
.salamander-icon { background-image: url('/images/salamander.png'); }
1. @each 多個(gè)分配
語法:
@each $var1, $var2, $var3 ... in <list>說明:<list> 表示列表的列表,每個(gè)變量將保存子列表的元素
$mul-list: (puma, black, default), (slug, blue, pointer), (egret, white, move);
@each $animal, $color, $cursor in $mul-list {
.#{$animal}-icon {
background: url('/images/#{$animal}.png');
border-color: 2px solid $color;
cursor: $cursor;
}
}
// 編譯結(jié)果
.puma-icon { background: url('/images/puma.png'); border-color: black; cursor: default; }
.slug-icon { background: url('/images/slug.png'); border-color: blue; cursor: pointer; }
.egret-icon { background: url('/images/egret.png'); border-color: white; cursor: move; }
2. @each 多個(gè)分配與映射
語法:
@each $var1, $var2 in <map>說明:<map> 表示鍵值對(duì)的列表
$mul-map: (h1: red, h2: green, h3: blue);
@each $header, $color in $mul-map {
#{$header} {
color: $color;
}
}
// 編譯結(jié)果
h1 { color: red; } h2 { color: green; } h3 { color: blue; }
@while
@while 指令重復(fù)輸出格式直到表達(dá)式返回結(jié)果為 false。這樣可以實(shí)現(xiàn)比 @for 更復(fù)雜的循環(huán),只是很少會(huì)用到。
語法: while(condition) { // CSS codes... }
說明:要注意,計(jì)數(shù)器變量需要在每次迭代時(shí)遞增/遞減。
$i: 30;
@while $i > 0 {
.paddding-#{$i} { padding-left: 1px * $i; }
$i: $i - 10; // 計(jì)數(shù)器變量在每次迭代時(shí)遞減
}
// 編譯結(jié)果
.paddding-30 { padding-left: 30px; }
.paddding-20 { padding-left: 20px; }
.paddding-10 { padding-left: 10px; }
七、混合指令 (Mixin Directives)
? Mixins允許創(chuàng)建一組可以在整個(gè)樣式表中重復(fù)使用的樣式,而不需要重新創(chuàng)建非語義類?;旌现噶羁梢园?strong>所有的 CSS 規(guī)則,絕大部分 Sass 規(guī)則,甚至通過參數(shù)功能引入變量,輸出多樣化的樣式。
? 在CSS中,mixin可以存儲(chǔ)多個(gè)值或參數(shù)和調(diào)用函數(shù); 它有助于避免編寫重復(fù)的代碼?;旌厦Q可以交替使用下劃線和連字符。
7.1 定義 @mixin
混合指令的用法是在 @mixin 后添加名稱與樣式
語法: @mixin 混合指令名稱 { // css code, sass code ... }
// 定義混合指令 clearfix
@mixin clearfix {
display: inline-block;
&:after { // 使用父選擇器標(biāo)識(shí)符
content: ".";
height: 0;
clear: both;
visibility: hidden;
}
* html & { height: 1px }
}
7.2 引用 @include
? @include 指令用于在文檔中引用混合樣式mixin。格式是在其后添加混合名稱,并傳遞需要的參數(shù)(可選)。由mixin定義的樣式可以包含在當(dāng)前規(guī)則中。
語法: @include 混合指令名稱( 參數(shù)[可選] )
.page-title {
@include clearfix;
}
// 編譯結(jié)果
.page-title { display: inline-block; }
.page-title:after { content: "."; height: 0; clear: both; visibility: hidden; }
* html .page-title { height: 1px; }
也可以在最外層引用混合樣式,不會(huì)直接定義屬性,也不可以使用父選擇器
@mixin silly-links {
a {
color: blue;
background-color: red;
}
}
@include silly-links;
// 編譯結(jié)果
a { color: blue; background-color: red; }
混合樣式中也可以包含其他混合樣式
@mixin highlighted-background { background-color: #fc0; }
@mixin header-text { font-size: 20px; }
@mixin compound {
@include highlighted-background;
@include header-text;
}
混合樣式中應(yīng)該只定義后代選擇器,這樣可以安全的導(dǎo)入到文件的任何位置。
7.3 參數(shù) (Arguments)
? 參數(shù)用于給混合指令中的樣式設(shè)定變量,并且賦值使用。在定義混合指令的時(shí)候,按照變量的格式,通過逗號(hào)分隔,將參數(shù)寫進(jìn)圓括號(hào)里。引用指令時(shí),按照參數(shù)的順序,再將所賦的值對(duì)應(yīng)寫進(jìn)括號(hào):
定義: @mixin 混合指令名稱(
param2, ... ) { // css code, sass code... }
引用: @include 混合指令名稱(
val2, ... )
@mixin sexy-border($color, $width: 1in) { // 定義了兩個(gè)參數(shù)$color和$width, $width的缺省值為1in
border: {
color: $color;
width: $width;
style: dashed;
}
}
p { @include sexy-border(blue); } // 只傳入一個(gè)參數(shù)$color, 使用$width的默認(rèn)值
h1 { @include sexy-border(blue, 2in); } // 傳入兩個(gè)參數(shù)
// 編譯結(jié)果
p { border-color: blue; border-width: 1in; border-style: dashed; }
h1 { border-color: blue; border-width: 2in; border-style: dashed; }
1. 關(guān)鍵詞參數(shù) (Keyword Arguments)
混合指令也可以使用關(guān)鍵詞參數(shù),上面的例子也可以寫成:
p { @include sexy-border($color: blue); }
h1 { @include sexy-border($color: blue, $width: 2in); }
? 雖然不夠簡(jiǎn)明,但是閱讀起來會(huì)更方便。關(guān)鍵詞參數(shù)給函數(shù)提供了更靈活的接口,以及容易調(diào)用的參數(shù)。關(guān)鍵詞參數(shù)可以打亂順序使用,如果使用默認(rèn)值也可以省缺,另外,參數(shù)名被視為變量名,下劃線、短橫線可以互換使用。
2. 參數(shù)變量 (Variable Arguments)
? 有時(shí),不能確定混合指令需要使用多少個(gè)參數(shù),比如一個(gè)關(guān)于 box-shadow 的混合指令不能確定有多少個(gè) 'shadow' 會(huì)被用到。這時(shí),可以使用參數(shù)變量 … 聲明(寫在參數(shù)的最后方)告訴 Sass 將這些參數(shù)視為值列表處理:
@mixin box-shadow($shadows...) { // 參數(shù)變量 用于定義mixin
-moz-box-shadow: $shadows;
-webkit-box-shadow: $shadows;
box-shadow: $shadows;
}
.shadows {
@include box-shadow(0px 4px 5px #666, 2px 6px 10px #999);
}
// 編譯為
.shadowed {
-moz-box-shadow: 0px 4px 5px #666, 2px 6px 10px #999;
-webkit-box-shadow: 0px 4px 5px #666, 2px 6px 10px #999;
box-shadow: 0px 4px 5px #666, 2px 6px 10px #999;
}
參數(shù)變量也可以用在引用混合指令的時(shí)候 (@include),與平時(shí)用法一樣,將一串值列表中的值逐條作為參數(shù)引用:
@mixin colors($text, $background, $border) {
color: $text;
background-color: $background;
border-color: $border;
}
$values: #ff0000, #00ff00, #0000ff;
.primary {
@include colors($values...); // 參數(shù)變量 用于引用mixin
}
// 編譯為
.primary {
color: #ff0000;
background-color: #00ff00;
border-color: #0000ff;
}
? 可以使用變量參數(shù)包裝mixin并添加其他樣式,而無需更改mixin的參數(shù)簽名。如果這樣做,甚至關(guān)鍵字參數(shù)都將傳遞到包裝的mixin。例如:
@mixin wrapped-stylish-mixin($args...) {
font-weight: bold;
@include stylish-mixin($args...);
}
.stylish {
// The $width argument will get passed on to "stylish-mixin" as a keyword
@include wrapped-stylish-mixin(#00ff00, $width: 100px);
}
7.4 向混合樣式中導(dǎo)入內(nèi)容
? 在引用混合樣式的時(shí)候,可以先將一段代碼導(dǎo)入到混合指令中,然后再輸出混合樣式,額外導(dǎo)入的部分將出現(xiàn)在 @content 標(biāo)志的地方。
注意: 當(dāng) @content 在指令中出現(xiàn)過多次或者出現(xiàn)在循環(huán)中時(shí),額外的代碼將被導(dǎo)入到每一個(gè)地方。
@mixin apply-to-ie6-only {
* html {
@content; // @content將被替換成 傳入的代碼塊
}
}
@include apply-to-ie6-only {
#logo {
background-image: url(/logo.gif);
}
}
// * html #logo { background-image: url(/logo.gif); }
為便于書寫,@mixin 可以用 = 表示,而 @include 可以用 + 表示,所以上面的例子可以寫成:
=apply-to-ie6-only
* html
@content
+apply-to-ie6-only
#logo
background-image: url(/logo.gif)
? 傳遞給mixin的內(nèi)容塊是在定義塊的作用域中計(jì)算的,而不是在mixin的作用域中。這意味著不能在傳遞的樣式塊中使用mixin的本地變量,并且變量將解析為全局值
$color-1: white;
$color: red;
@mixin colors($color: blue) {
background-color: $color;
@content;
border-color: $color;
}
.colors {
@include colors { color: $color-1; } //傳遞的內(nèi)容塊在引用時(shí)就計(jì)算,所以引用的變量不能時(shí)mixin內(nèi)的
}
// 編譯結(jié)果
.colors { background-color: blue; color: white; border-color: blue; }
八、函數(shù)指令 (Function Directives)
Sass 支持自定義函數(shù),并能在任何屬性值或 Sass script 中使用
- 【命名約定】為了避免命名沖突,函數(shù)名稱可以帶前綴,以便可以輕松區(qū)分;函數(shù)和其他Sass標(biāo)識(shí)符可以交替使用下劃線(_)和連字符( - )
- 就像mixin一樣,函數(shù)也可以訪問全局定義的變量,也可以接受參數(shù),也支持變量參數(shù)。
- 應(yīng)該使用 @return 來調(diào)用函數(shù)的返回值。
- 可以使用關(guān)鍵字參數(shù)調(diào)用SASS定義的函數(shù)
fn-name( $param1: val1, $param2: val2 ... )
$grid-width: 40px;
$gutter-width: 10px;
@function grid-width($n) {
@return $n * $grid-width + ($n - 1) * $gutter-width;
}
#sidebar { width: grid-width(5); } // 使用關(guān)鍵字參數(shù)調(diào)用 width: grid-width($n: 5);