CSS預(yù)處理器 —— Sass學(xué)習(xí)筆記(基礎(chǔ))
參考
- scss官網(wǎng)
- SCSS 里的數(shù)組及其遍歷 https://blog.csdn.net/weixin_42703239/article/details/104181830
- 【譯】介紹Sass Maps:用法跟例子 https://blog.csdn.net/qq_41903941/article/details/90259385
一、sass簡(jiǎn)介
1. 特色功能
- 完全兼容 CSS3
- 在 CSS 基礎(chǔ)上增加 變量 (variables)娘扩、嵌套 (nested rules)着茸、混合 (mixins)、導(dǎo)入 (inline imports) 等功能
- 通過函數(shù)進(jìn)行顏色值與屬性值的運(yùn)算
- 提供控制指令 (control directives)等高級(jí)功能
- 自定義輸出格式
2. 語(yǔ)法格式
Sass 有兩種語(yǔ)法格式琐旁。
首先是 SCSS (Sassy CSS)
- 這種格式以
.scss
作為拓展名 - 這種格式僅在 CSS3 語(yǔ)法的基礎(chǔ)上進(jìn)行拓展牺陶,所有 CSS3 語(yǔ)法在 SCSS 中都是通用的,同時(shí)加入 Sass 的特色功能梳猪。
- SCSS 也支持大多數(shù) CSS hacks 寫法以及瀏覽器前綴寫法 (vendor-specific syntax)逃呼,以及早期的 IE 濾鏡寫法。
另一種也是最早的 Sass 語(yǔ)法格式
- 被稱為縮進(jìn)格式 (Indented Sass) 隙姿,通常簡(jiǎn)稱 "Sass"奈嘿,是一種簡(jiǎn)化格式掺冠。
- 這種格式以
.sass
作為拓展名 - 它使用 <u>“縮進(jìn)” 代替 “花括號(hào)” 表示屬性屬于某個(gè)選擇器</u>憾股,用 <u>“換行” 代替 “分號(hào)” 分隔屬性</u>婉商,很多人認(rèn)為這樣做比 SCSS 更容易閱讀肠牲,書寫也更快速。
- 縮進(jìn)格式也可以使用 Sass 的全部功能绞蹦,只是與 SCSS 相比個(gè)別地方采取了不同的表達(dá)方式亭饵,具體請(qǐng)查看 the indented syntax reference骤肛。
任何一種格式可以直接 導(dǎo)入 (@import)
到另一種格式中使用毁嗦,或者通過 sass-convert
命令行工具轉(zhuǎn)換成另一種格式:
# 將 Sass 轉(zhuǎn)換成 SCSS
$ sass-convert style.sass style.scss
# Convert SCSS to Sass
$ sass-convert style.scss style.sass
3. 安裝
sass
基于Ruby
語(yǔ)言開發(fā)而成氨鹏,window下安裝 sass
首先需要 安裝Ruby纪挎。(注: mac下自帶Ruby無需在安裝Ruby!)
3.1 Ruby安裝
? 先從官網(wǎng)下載Ruby,安裝過程中請(qǐng)注意勾選 Add Ruby executables to your PATH
添加到系統(tǒng)環(huán)境變量蜘矢。如下圖:
? 安裝完成后需測(cè)試安裝有沒有成功哑姚,運(yùn)行CMD
輸入以下命令:
ruby -v
# 如安裝成功會(huì)打印
ruby 2.6.4p104 (2019-08-28 revision 67798) [x64-mingw32]
3.2 Sass安裝
? Ruby
自帶一個(gè)叫做 RubyGems
的系統(tǒng),用來安裝基于Ruby
的軟件咳短。我們可以使用這個(gè)系統(tǒng)來 輕松地安裝Sass
和Compass
米死。要安裝最新版本的Sass
和Compass
材蹬,你需要輸入下面的命令:
# 安裝如下(如mac安裝遇到權(quán)限問題需加 sudo gem install sass)
gem install sass
gem install compass
? 安裝完成之后汇跨,你應(yīng)該通過運(yùn)行下面的命令來確認(rèn)應(yīng)用已經(jīng)正確地安裝到了電腦中:
sass -v
# Sass 3.x.x (Selective Steve)
compass -v
# Compass 1.x.x (Polaris)
# ...
? 如下sass常用更新澡腾、查看版本、sass命令幫助等命令:
# 更新sass
gem update sass
# 查看sass版本
sass -v
# 查看sass幫助
sass -h
3.3 編譯sass
? sass
編譯有很多種方式登钥,如命令行編譯模式轮纫、sublime插件SASS-Build
情连、編譯軟件koala
搀崭、前端自動(dòng)化軟件codekit
获茬、Grunt打造前端自動(dòng)化工作流grunt-sass
、Gulp打造前端自動(dòng)化工作流gulp-ruby-sass
等倔既。
3.3.1 命令行編譯模式
? Sass 命令行工具根據(jù)文件的拓展名判斷所使用的語(yǔ)法格式锦茁,沒有文件名時(shí) sass
命令默認(rèn)編譯 .sass
文件,添加 --scss
選項(xiàng)或者使用 scss
命令編譯 SCSS 文件
# 單文件轉(zhuǎn)換命令 sass 源文件 目標(biāo)文件
sass input.scss output.css
# 單文件監(jiān)聽命令 sass --watch 源文件:目標(biāo)文件
sass --watch input.scss:output.css
# 監(jiān)聽整個(gè)文件夾
sass --watch app/sass:public/stylesheets
# 編譯格式 --style表示解析后的css是什么排版格式
# sass內(nèi)置有四種編譯格式: nested | expanded | compact | compressed
sass --watch input.scss:output.css --style compact
# 編譯添加調(diào)試map
# --sourcemap表示開啟sourcemap調(diào)試, 開啟sourcemap調(diào)試后叉存,會(huì)生成一個(gè)后綴名為.css.map文件
sass --watch input.scss:output.css --sourcemap
# 選擇編譯格式并添加調(diào)試map
sass --watch input.scss:output.css --style expanded --sourcemap
# 開啟debug信息
sass --watch input.scss:output.css --debug-info
sass的四種編譯風(fēng)格:
nested:嵌套縮進(jìn)的css代碼码俩,它是默認(rèn)值。
expanded:沒有縮進(jìn)的歼捏、擴(kuò)展的css代碼稿存。
compact:簡(jiǎn)潔格式的css代碼(一種選擇器的規(guī)則在單獨(dú)一行)。
compressed:壓縮后的css代碼瞳秽。
3.3.2 軟件方式編譯
- 推薦國(guó)產(chǎn)免費(fèi)圖形編譯工具 Koala
- VScode擴(kuò)展 Live Sass
"liveSassCompile.settings.formats":[
// 擴(kuò)展
{
//可定制的出口CSS樣式(expanded瓣履,compact,compressed练俐,nested)
"format": "compact",
"extensionName": ".min.css",//編譯后綴名
"savePath": null//編譯保存的路徑
}
],
"liveSassCompile.settings.excludeList": [
"**/node_modules/**",
".vscode/**"
],
二袖迎、嵌套規(guī)則(css功能擴(kuò)展)
1 后代選擇器
? Sass 允許將 <u>一套 CSS 樣式</u> 嵌套進(jìn) <u>另一套樣式中</u>,內(nèi)層的樣式將它外層的選擇器 <u>作為父選擇器</u>腺晾。嵌套功能 <u>避免了重復(fù)輸入父選擇器</u>燕锥,而且令復(fù)雜的 CSS 結(jié)構(gòu)更易于管理。
? 在Sass中悯蝉,你可以像俄羅斯套娃那樣在規(guī)則塊中嵌套規(guī)則塊归形。sass
在輸出css
時(shí)會(huì)幫你把這些嵌套規(guī)則處理好,避免你的重復(fù)書寫:
#main {
color: #00ff00;
width: 97%;
.redbox {
background-color: #ff0000;
color: #000000;
}
}
? 編譯結(jié)果(sass --watch demo.sass:demo.css --style compact)
#main {color: #00ff00; width: 97%; }
#main .redbox {background-color: #ff0000; color: #000000; }
過程:sass
用了兩步鼻由,每一步都是像打開俄羅斯套娃那樣把里邊的嵌套規(guī)則塊一個(gè)個(gè)打開暇榴。
- 首先厚棵,把
#main
(父級(jí))這個(gè)id
放到.redbox
選擇器(子級(jí))的前邊; - 然后蔼紧,
#main .redbox
里邊還有嵌套的規(guī)則婆硬,sass
重復(fù)一遍上邊的步驟,把新的選擇器添加到內(nèi)嵌的選擇器前邊
大多數(shù)情況下這種簡(jiǎn)單的嵌套都沒問題奸例,但是有些場(chǎng)景下不行彬犯,比如你想要在嵌套的選擇器 里邊立刻應(yīng)用一個(gè)類似于:hover
的偽類。為了解決這種以及其他情況哩至,sass
提供了一個(gè)特殊結(jié) 構(gòu)&
躏嚎。
2 父選擇器的標(biāo)識(shí)符&
? 一般情況下蜜自,sass
在解開一個(gè)嵌套規(guī)則時(shí)就會(huì)把父選擇器(#main
)通過一個(gè)空格連接到子選擇器的前邊(.redbox
)形成(#main .redbox
)菩貌。這種在CSS里邊被稱為后代選擇器,因?yàn)樗x擇ID為 main
的元素內(nèi)所有命中選擇器.redbox
的元素重荠。但在有些情況下你卻不會(huì)希望sass
使用這種后代選擇器的方式生成這種連接箭阶。
用法一:作為普通的父選擇器
? <u>最常見的一種情況是當(dāng)你為鏈接之類的元素寫:hover
這種偽類時(shí)</u>,你并不希望以后代選擇器的方式連接戈鲁。比如說仇参,下面這種情況sass
就無法正常工作:
article a {
color: blue;
:hover { color: red }
}
? 這意味著color: red
這條規(guī)則將會(huì)被應(yīng)用到選擇器article a :hover
,article
元素內(nèi)鏈接的所有子元素在被hover
時(shí)都會(huì)變成紅色婆殿。這與我們的初衷是不符合的诈乒。
解決之道為使用一個(gè)特殊的sass
選擇器,即父選擇器婆芦。在使用嵌套規(guī)則時(shí)怕磨,父選擇器能對(duì)于嵌套規(guī)則如何解開提供更好的控制。它就是一個(gè)簡(jiǎn)單的&
符號(hào)消约,且可以放在任何一個(gè)選擇器可出現(xiàn)的地方 肠鲫。
article a {
color: blue;
&:hover { color: red }
}
? 當(dāng)包含父選擇器標(biāo)識(shí)符的嵌套規(guī)則被打開時(shí),它不會(huì)像后代選擇器那樣進(jìn)行拼接或粮,而是&
被父選擇器直接替換:
article a { color: blue }
article a:hover { color: red }
用法二:在父選擇器之前添加選擇器
? 比如导饲,在js
代碼中根據(jù)瀏覽器判斷,是IE
時(shí)就給body
標(biāo)簽添加一個(gè) .ie
選擇器氯材,為這種情況編寫特殊的樣式如下:
#content aside {
color: red;
body.ie & { color: green } // 在父選擇器之前添加選擇器 body.ie
}
// 編譯后
#content aside {color: red};
body.ie #content aside { color: green }
用法三:用作選擇器名稱的占位符
? <u>&
必須作為選擇器的第一個(gè)字符</u>渣锦,其后可以跟隨后綴生成復(fù)合的選擇器,例如
#main {
color: black;
&-sidebar { border: 1px solid; } // 用作占位符氢哮,編譯時(shí)會(huì)用父選擇器的名稱替換&
}
// 編譯后
#main {color: black; }
#main-sidebar {border: 1px solid; }
? 注意:當(dāng)父選擇器含有不合適的后綴時(shí)泡挺,Sass 將會(huì)報(bào)錯(cuò)。
3 群組選擇器的嵌套
? 在CSS
里邊命浴,選擇器 button
會(huì)同時(shí)命中所有的 button
元素娄猫。這種選擇器稱為群組選擇器贱除。群組選擇器 的規(guī)則會(huì)對(duì)命中群組中任何一個(gè)選擇器的元素生效。
.container {
h1, h2, h3 {
a {margin-bottom: .8em}
}
}
? 當(dāng)sass
解開一個(gè)群組選擇器規(guī)則內(nèi)嵌的規(guī)則時(shí)媳溺,它會(huì)把每一個(gè)內(nèi)嵌選擇器的規(guī)則都正確地解出來:
// 編譯后
.container h1 a, .container h2 a, .container h3 a { margin-bottom: .8em }
? 過程:首先sass
將.container
和h1
月幌、.container
和h2
、.container
和h3
分別組合悬蔽,然后將三者重新組合成一個(gè)群組選擇器扯躺。然后對(duì)于內(nèi)嵌在群組選擇器內(nèi)的嵌 套規(guī)則,處理方式也一樣蝎困,將.container h1
和a
录语、.container h2
和a
、.container h3
和a
再分別組合禾乘,然后重新組合成一個(gè)群組選擇器澎埠,生成上面的普通css樣式。
? 缺點(diǎn):雖然sass
讓你的樣式表看上去很小始藕,但實(shí)際生成的css
卻可能非常大蒲稳,這會(huì)降低網(wǎng)站的速度。
4 子組合選擇器 >
和同層組合選擇器:+
和 ~
? 這三個(gè)組合選擇器 <u>必須和其他選擇器配合使用</u>伍派,以指定瀏覽器僅選擇某種特定上下文中的元素江耀。
article {
> section { background: #eee } // 直接子元素 >
nav + & { margin-top: 0 } // 父選擇器之前添加選擇器
~ article { border-top: 1px dashed #ccc } // 同層組合選擇器 ~
dl > {
dt { color: #333 }
dd { color: #555 }
}
}
? 編譯結(jié)果
// 子組合選擇器> : 選擇article的直接子元素footer
article > footer { background: #eee }
// 同層組合選擇器~ : 選擇nav后緊跟的article元素
nav + article { margin-top: 0 }
// 同層全體組合選擇器~ : 選擇所有跟在article后的同層article元素,不管它們之間隔了多少其他元素
article ~ article { border-top: 1px dashed #ccc }
article dl > dt { color: #333 }
article dl > dd { color: #555 }
5 嵌套屬性
? 有些 CSS 屬性遵循相同的命名空間 (namespace)诉植,比如 font-family, font-size, font-weight
都以 font
作為屬性的命名空間祥国。為了便于管理這樣的屬性,同時(shí)也為了避免了重復(fù)輸入晾腔,Sass 允許將屬性嵌套在命名空間中
嵌套屬性的規(guī)則是這樣的:把屬性名從中劃線
-
的地方斷開舌稀,在根屬性后邊添加一個(gè)冒號(hào):
,緊跟一個(gè){ }
塊建车,把子屬性部分寫在這個(gè){ }
塊中扩借。
就像css
選擇器嵌套一樣,sass
會(huì)把你的子屬性一一解開缤至,把根屬性和子屬性部分通過中劃線-連接起來潮罪,最后生成的效果與你手動(dòng)一遍遍寫的css
樣式一樣
nav {
border: {
style: solid;
width: 1px;
color: #ccc;
}
}
// 編譯后
nav {
border-style: solid;
border-width: 1px;
border-color: #ccc;
}
命名空間也可以包含自己的屬性值,例如:
.funky {
font: 20px/24px {
family: 'Microsoft Yahei';
weight: bold;
}
}
// 編譯后
.funky {
font: 20px/24px;
font-family: fantasy;
font-weight: bold;
}
對(duì)于屬性的縮寫形式领斥,你甚至可以像下邊這樣來嵌套嫉到,指明例外規(guī)則:
nav {
border: 1px solid #ccc {
left: 0px;
right: 0px;
}
}
// 編譯后
nav {
border: 1px solid #ccc;
border-left: 0px;
border-right: 0px;
}
6 占位符選擇器 %foo
? Sass 額外提供了一種特殊類型的選擇器:占位符選擇器 (placeholder selector)。與常用的 id 與 class 選擇器寫法相似月洛,只是 #
或 .
替換成了 %
何恶。必須通過 @extend 指令調(diào)用,更多介紹請(qǐng)查閱 @extend-Only Selectors嚼黔。
? 當(dāng)占位符選擇器單獨(dú)使用時(shí)(未通過 @extend
調(diào)用)细层,不會(huì)編譯到 CSS 文件中惜辑。
三、 注釋
? Sass 支持標(biāo)準(zhǔn)的 CSS 多行注釋 /* */
疫赎,以及單行注釋 //
盛撑,前者會(huì) 被完整輸出到編譯后的 CSS 文件中,而后者則不會(huì)
? 將 !
作為多行注釋的第一個(gè)字符表示在壓縮輸出模式下保留這條注釋并輸出到 CSS 文件中捧搞,通常用于添加版權(quán)信息抵卫。
? 插值語(yǔ)句 (interpolation) 也可寫進(jìn)多行注釋中輸出變量值:
$version: "1.2.3";
/* This CSS is generated by My Snazzy Framework version #{$version}. */
// 編譯為
/* This CSS is generated by My Snazzy Framework version 1.2.3. */
四、sassScript
? 在 CSS 屬性的基礎(chǔ)上 Sass 提供了一些名為 SassScript 的新功能胎撇。 SassScript 可作用于任何屬性介粘,允許屬性使用變量、算數(shù)運(yùn)算等額外功能晚树。
? 通過 interpolation姻采,SassScript 甚至可以生成選擇器或?qū)傩悦@一點(diǎn)對(duì)編寫 mixin 有很大幫助题涨。
4.1 Interactive Shell
Interactive Shell 可以在命令行中測(cè)試 SassScript 的功能偎谁。在命令行中輸入 sass -i
总滩,然后輸入想要測(cè)試的 SassScript 查看輸出結(jié)果:
$ sass -i
>> "Hello, Sassy World!"
"Hello, Sassy World!"
>> 1px + 1px + 1px
3px
>> #777 + #777
#eeeeee
>> #777 + #888
white
4.2 變量$
? sass
使用$
符號(hào)來標(biāo)識(shí)變量(老版本的sass
使用!
來標(biāo)識(shí)變量纲堵。改成highlight-color和
符號(hào)呢席函?因?yàn)樗谜J(rèn)、更具美感冈涧,且在CSS中并無他用茂附,不會(huì)導(dǎo)致與現(xiàn)存或未來的
css`語(yǔ)法沖突。
1. 變量命名
? sass
的變量名可以與css
中的屬性名和選擇器名稱相同督弓,包括中劃線和下劃線(使用中劃線的方式更為普遍)营曼。這兩種用法fu相互兼容。用中劃線聲明的變量可以使用下劃線的方式引用愚隧,反之亦然蒂阱。這意味著即使compass
選擇用中劃線的命名方式,這并不影響你在使用compass
的樣式中用下劃線的命名方式進(jìn)行引用:
$link-color: blue; // 中劃線方式命名
a { color: $link_color; } // 可以通過 下劃線 方式引用
//編譯后
a { color: blue; }
? 注意:在sass
中純css
部分不互通狂塘,比如類名录煤、ID或?qū)傩悦?/p>
2. 變量聲明
? 變量以美元符號(hào)開頭,賦值方法與 CSS 屬性的寫法一樣荞胡;
$highlight-color: #F90;
// 以空格分割的多個(gè)屬性值
$basic-border: 1px solid black;
// 以逗號(hào)分割的多個(gè)屬性值
$plain-font: Myriad,Helvetica,"Liberation Sans",Arial,sans-serif;
- 任何可以用作
css
屬性值的賦值都可以用作sass
的變量值妈踊。 - 變量聲明后還未生效,只有當(dāng)變量被引用后才生效
- 在聲明變量時(shí)泪漂,變量值也可以引用其他變量廊营。
$highlight-color: #F90;
$highlight-border: 1px solid $highlight-color; // 聲明變量時(shí)歪泳,變量值也可以引用其他變量
.selected {
border: $highlight-border; // 當(dāng)變量被引用后才生效
}
//編譯后
.selected {border: 1px solid #F90;}
3. 變量引用
1. 凡是`css`屬性的標(biāo)準(zhǔn)值可存在的地方,變量就可以使用露筒。`css`生成時(shí)夹囚,變量會(huì)被它們的值所替代。
2. 變量可以修改邀窃,但一經(jīng)修改荸哟,**所有**引用此變量的地方(**同一作用域**)生成的值**都會(huì)隨之改變**
3. 如果變量要**鑲嵌在字符串之中**,就必須需要寫在 **`#{}`**之中瞬捕,也就是后面要講到的 **插值語(yǔ)句**
$side : top-left;
.rounded { border-#{$side}-radius: 5px; }
// 編譯后
.rounded { border-top-left-radius: 5px; }
4. 變量作用域
1. 全局作用域:不在嵌套規(guī)則內(nèi)定義的變量則可在任何地方使用(嵌套規(guī)則外 -- 全局變量)
2. 塊級(jí)作用域:嵌套規(guī)則內(nèi)定義的變量只能在嵌套規(guī)則內(nèi)使用(嵌套規(guī)則內(nèi) -- 局部變量)
3. 將局部變量轉(zhuǎn)換為全局變量可以添加 `!global` 聲明(嵌套規(guī)則內(nèi) -- 全局變量 -- $變量名: 變量值 !global;)
#main {
$width: 5em !global; // 加了!global則$width變成了全局變量
width: $width;
}
#sidebar {
width: $width;
}
4.3 數(shù)據(jù)類型
SassScript 支持 6 種主要的數(shù)據(jù)類型(變量的6中主要數(shù)據(jù)類型):
-
數(shù)字鞍历,
1, 2, 13, 10px
-
字符串,有引號(hào)字符串與無引號(hào)字符串肪虎,
"foo", 'bar', baz
-
顏色劣砍,
blue, #04a3f9, rgba(255,0,0,0.5)
-
布爾型,
true, false
-
空值扇救,
null
-
數(shù)組 (list)刑枝,用空格或逗號(hào)作分隔符,
1.5em 1em 0 2em, Helvetica, Arial, sans-serif
-
maps, 相當(dāng)于 JavaScript 的 object迅腔,
(key1: value1, key2: value2)
SassScript 也支持其他 CSS 屬性值装畅,比如 Unicode 字符集,或 !important
聲明沧烈。然而Sass 不會(huì)特殊對(duì)待這些屬性值掠兄,一律視為無引號(hào)字符串
1. 字符串
- 有引號(hào)字符串 (quoted strings) :如
"Lucida Grande"
'Microsoft Yahei'
; - 無引號(hào)字符串 (unquoted strings)锌雀,如
sans-serif
蚂夕、bold
,在編譯 CSS 文件時(shí)不會(huì)改變其類型
$font-family: 'Microsoft Yahei', sans-serif; // 一個(gè)有引號(hào)字符串腋逆,一個(gè)無引號(hào)字符串
body {
// 嵌套屬性的寫法
font: 14px/24px {
family: $font-family;
};
}
// 編譯后. 可發(fā)現(xiàn)在編譯css文件時(shí)不會(huì)改變字符串的類型
body { font: 14px/24px; font-family: "Microsoft Yahei", sans-serif; }
- 例外情況:使用
#{}
(插值) 時(shí)婿牍,有引號(hào)字符串將被編譯為無引號(hào)字符串,這樣便于在 mixin 中引用選擇器名:
@mixin firefox-message($selector) {
body.firefox #{$selector}:before {//會(huì)將傳入的有引號(hào)字符串".header"編譯成了無引號(hào)字符串
content: "Hi, Firefox users!";
}
}
@include firefox-message(".header");
// 編譯后
body.firefox .header:before {content: "Hi, Firefox users!"; }
2. 顏色
? 任何CSS顏色表達(dá)式都返回一個(gè)SassScript顏色值惩歉,這包括大量與未引用字符串無法區(qū)分的命名顏色等脂。在壓縮輸出模式下,Sass將輸出顏色的最小CSS表示柬泽。例如慎菲,#FF0000在壓縮模式下將輸出為red,而blanchedalmond將輸出為#FFEBCD锨并。
$color: #ff0000;
body {
color: $color;
p {color: #ff0000;}
}
// 編譯后 sass --watch demo.scss:demo.css --style compressed
body { color:red; }
body p { color: #ff0000; }
? 用戶在使用命名顏色時(shí)遇到的一個(gè)常見問題是露该,由于Sass首選的輸出格式與在其他輸出模式中鍵入的格式相同,因此在壓縮時(shí)插入選擇器的顏色將成為無效語(yǔ)法第煮。為了避免這種情況解幼,如果要在選擇器的構(gòu)造中使用命名顏色抑党,請(qǐng)始終引用它們。
3. 數(shù)組 (Lists)
? 數(shù)組 (lists) 指 Sass 如何處理 CSS 中 margin: 10px 15px 0 0
或者 font-face: Helvetica, Arial, sans-serif
這樣通過 空格 或者 逗號(hào) 分隔的一系列的值撵摆。事實(shí)上底靠,獨(dú)立的值也被視為數(shù)組 —— 只包含一個(gè)值的數(shù)組。
數(shù)組本身沒有太多功能特铝,但 Sass list functions 賦予了數(shù)組更多新功能:
-
length()
獲取數(shù)組長(zhǎng)度 -
index($list, $value)
返回一個(gè)值在列表中的位置值 -
nth($list, $index)
函數(shù)可以直接訪問數(shù)組中的某一項(xiàng)暑中; -
join($list1, $list2, [$separator])
函數(shù)可以將多個(gè)數(shù)組連接在一起; -
append($list, $val, [$separator])
函數(shù)可以在數(shù)組中添加新值鲫剿; -
zip($lists…)
將幾個(gè)列表結(jié)合成一個(gè)多維的列表鳄逾。。 -
@each
指令能夠遍歷數(shù)組中的每一項(xiàng)灵莲。
示例:實(shí)現(xiàn)下面這種效果雕凹。HTML 結(jié)構(gòu)很簡(jiǎn)單,就是一個(gè) ul 政冻,下面 6 個(gè)li枚抵,每個(gè) li 的背景色不一樣。
用傳統(tǒng)CSS來寫:
.ksxz_ul li:nth-child(1){
background:#f5ad1b;
}
.ksxz_ul li:nth-child(1):hover{
background:#f7bf4c;
}
// 明场。汽摹。。
以下代碼是在 SCSS 中完成:
// 定義數(shù)組榕堰,數(shù)組元素用逗號(hào)隔開
$liColor: #f5ad1b,#5f89ce,#94bf45,#da8ec5,#78bfc2,#bec278;
// 開始 @each 循環(huán)遍歷數(shù)組
// $c 作為循環(huán)變量竖慧,代表了數(shù)組的元素嫌套,不是索引~D媛拧!踱讨!
@each $c in $liColor{
$i:index($liColor, $c); // 獲取 $c 在數(shù)組中的索引魏蔗,并賦值給 $i 賦值用冒號(hào),不是等號(hào)~痹筛!
li:nth-child( #{$i} ){ // 經(jīng)典的地方來了莺治,SCSS 循環(huán)是從 1 開始,不是 0 哦~
background: $c; // 背景色
&:hover{
background: lighten($c, 10%); // hover 后的顏色
}
}
}
數(shù)組中可以包含子數(shù)組
- 比如
1px 2px, 5px 6px
是包含1px 2px
與5px 6px
兩個(gè)數(shù)組的數(shù)組帚稠。 - 如果內(nèi)外兩層數(shù)組使用相同的分隔方式谣旁,需要用圓括號(hào)包裹內(nèi)層,所以也可以寫成
(1px 2px) (5px 6px)
滋早。 - 區(qū)別就是榄审,之前的
1px 2px, 5px 6px
使用逗號(hào)分割了兩個(gè)子數(shù)組 (comma-separated),而(1px 2px) (5px 6px)
則使用空格分割(space-separated)杆麸。
當(dāng)數(shù)組被編譯為 CSS 時(shí)搁进,Sass 不會(huì)添加任何圓括號(hào)(CSS 中沒有這種寫法)
- 用
()
表示不包含任何值的空數(shù)組浪感。空數(shù)組不可以直接編譯成 CSS饼问,比如編譯font-family: ()
Sass 將會(huì)報(bào)錯(cuò)影兽。 - 如果數(shù)組中包含空數(shù)組或空值,編譯時(shí)將被清除莱革,比如
1px 2px () 3px
或1px 2px null 3px
峻堰。
p { font-family: (); } // 編譯將會(huì)報(bào)錯(cuò) Invalid CSS after "...font-family: ()"
$border: 1px 2px null 3px; // 或者 $border: 1px 2px () 3px;
.rounded {
border: $border ;
}
// 編譯后
.rounded { border: 1px 2px 3px; }
基于逗號(hào)分隔的數(shù)組允許保留結(jié)尾的逗號(hào),這樣做的意義是強(qiáng)調(diào)數(shù)組的結(jié)構(gòu)關(guān)系盅视,尤其是需要聲明只包含單個(gè)值的數(shù)組時(shí)茧妒。例如 (1,)
表示只包含 1
的數(shù)組,而 (1 2 3,)
表示包含 1 2 3
這個(gè)以空格分隔的數(shù)組的數(shù)組左冬。
4. Maps
? Maps可視為鍵值對(duì)的集合桐筏,鍵被用于定位值。
- 和Lists不同拇砰,Maps必須被圓括號(hào)包圍梅忌,鍵值對(duì)被逗號(hào)分割 。 Maps中的keys和values可以是sassscript的任何對(duì)象除破。
- 和Lists一樣Maps主要為sassscript函數(shù)服務(wù)牧氮,如 map-get函數(shù)用于查找鍵值,map-merge函數(shù)用于map和新加的鍵值融合瑰枫,@each命令可添加樣式到一個(gè)map中的每個(gè)鍵值對(duì)踱葛。
- Maps可用于任何Lists可用的地方,在List函數(shù)中 Map會(huì)被自動(dòng)轉(zhuǎn)換為L(zhǎng)ist 光坝, 如 (key1: value1, key2: value2)會(huì)被List函數(shù)轉(zhuǎn)換為 key1 value1, key2 value2 尸诽,反之則不能。
1. map-merge合并函數(shù)
2. map-get獲取函數(shù)
//創(chuàng)建Maps類型的變量: Maps變量的值必須由圓括號(hào)包圍盯另,鍵值對(duì)以逗號(hào)分隔
$testMaps1: ( size: 14px, color: pink );
$testMaps2: (
color: #666,
family: (Arial, Helvetica),
size: 16px,
line-height: 1.4
);
// map-merge函數(shù)性含,將兩個(gè)maps變量進(jìn)行合并,生成一個(gè)新的maps變量
$testMaps: map-merge($testMaps1, $testMaps2);
body{
// 通過map-get函數(shù)查找某個(gè)key的value鸳惯∩淘蹋可簡(jiǎn)寫成 font-size: map-get($testMaps, size)
// 注意,size/line-height要使用插值語(yǔ)句芝发,若是直接寫/將會(huì)被認(rèn)作是除號(hào)兽赁,從而進(jìn)行除法運(yùn)算
font: #{map-get($map: $testMaps, $key: size)}/#{map-get($testMaps, line-height)} {
family: map-get($testMaps, family)
}
color: map-get($testMaps, color);
}
// 編譯后
body { font: 16px; font-family: Arial, Helvetica; line-height: 1.4; color: #666; }
3. map-has-key判斷函數(shù)
// Map with much breakpoints
$breakpoints: (
small: 320px,
medium: 600px,
large: 768px
);
// Respond-To Mixin
@mixin respond-to($breakpoint) {
// map-has-key函數(shù)用于檢測(cè)某個(gè)key是否存在
@if map-has-key($breakpoints, $breakpoint) {
$value: map-get($breakpoints, $breakpoint);
@media screen and (min-width: $value) {
@content;
}
}
@warning "Unknown `#{$breakpoint}` in $breakpoints";
}
// 使用
.m-tabs {
background-color: #f2f2f2;
@include reponse-to(medium) {
background-color: #666;
}
}
// 編譯后
.m-tabs {
background-color: #f2f2f2;
}
@media screen and (min-width: 600px) {
background-color: #666;
}
4. @each 循環(huán)Maps變量
// 創(chuàng)建Maps類型的變量: Maps變量的值必須由圓括號(hào)包圍备燃,鍵值對(duì)以逗號(hào)分隔
$icons: (
checkmark: a,
plus: b,
minus: c
);
// @each $name, $value in 變量名 遍歷maps變量 $icon盗忱,輸出icons的所有類
@each $name, $value in $icons {
.icon--#{$name} {
content: $value;
}
}
// 編譯結(jié)果
.icon--checkmark { content: a; }
.icon--plus { content: b; }
.icon--minus { content: c; }
5. nth函數(shù)
// _m-buttons.scss
$buttons: (
error: (#d82d2d, #666), // 值是一個(gè)數(shù)組:(背景顏色, 字體顏色)
success: (#52bf4a, #fff),
warning: (#c23435, #fff)
);
.m-button {
display: inling-block;
padding: .5em;
background: #ccc;
color: #666;
@each $name, $colors in $buttons {
$bgcolor: nth($colors, 1); // 通過nth獲取數(shù)組中的第一項(xiàng)
$fontcolor: nth($colors, 2);// 通過nth獲取數(shù)組中的第二項(xiàng)
&--#{$name} {
background-color: $bgcolor;
color: $fontcolor;
}
}
}
// 編譯后
.m-button { display: inling-block; padding: .5em; background: #ccc; color: #666; }
.m-button--error { background-color: #d82d2d; color: #666; }
.m-button--success { background-color: #52bf4a; color: #fff; }
.m-button--warning { background-color: #c23435; color: #fff; }
6. 搭配函數(shù)使用
// _config.scss
$layer: (
offcanvas: 1,
lightbox: 500,
dropdown: 10,
tooltip: 15
);
// _m-lightboxes.scss
@function layer($name) {
@if map-has-key($layer, $name) {
@return map-get($layer, $name);
}
@warn "The key #{$name} is not in the map '$layer'";
@return null;
};
.m-lightbox {
z-index: layer(lightbox);
}
// 編譯后
.m-lightbox { z-index: 500; }
// Scheme of colors
$colorscheme: (
gray: (
base: #ccc,
light: #f2f2f2,
dark: #666
),
brown: (
base: #ab906b,
light: #ecdac3,
dark: #5e421c
)
);
// 顏色獲取函數(shù)
// 第一個(gè)參數(shù)是Sass map的對(duì)象($scheme) -- 在這個(gè)例子中可能是gray或者brown
// 第二個(gè)參數(shù)就是你想要的顏色($tone)展箱,默認(rèn)值是base
@function setcolor($scheme, $tone: base) {
@return map-get(map-get($colorscheme, $scheme), $tone);
}
// 使用
.element {
color: setcolor(brown);
}
.element--light {
color: setcolor(brown, light);
}
// 編譯后
.element { color: #ab906b; }
.element--light { color: #ecdac3; }
7. 高級(jí):通過Classes定制主題
? 在項(xiàng)目中會(huì)經(jīng)常需要通過一些基礎(chǔ)代碼創(chuàng)建多套主題,所以這里給出一個(gè)建議:在文檔的最開始就定義一個(gè) 主題類 來滿足特定的工作。我們需要一個(gè)對(duì)象以便能夠處理不同名字的主題理张,同時(shí)給出不同的樣式模塊赫蛇。
// _config.scss
$themes: (
theme1: theme-light,
theme2: theme-dark
);
$config: (
theme1: (
background: #f2f2f2,
color: #000
),
theme2: (
background: #666,
color: #fff
)
);
// 快速獲取模塊值的方法
// _functions.scss
@function setStyle($map, $theme, $style) {
@if map-has-key($map, $theme) {
@return map-get(map-get($map, $theme), $style);
}
@warn "The key `#{$object}` is not available in the map.";
@return null;
}
// 遍歷主題
// _m-buttons.scss
.m-button {
// 遍歷$themes拿到$key和$value,為不同主題創(chuàng)建map
@each $key, $value in $themes {
@if map-has-key($config, $key) {
.#{$value} & {
background: setStyle($config, $key, background);
color: setStyle($config, $key, color);
}
} @else {
@warn "The key `#{$key} isn't defined in the map $config`"
}
}
}
// 編譯后
.theme-light .m-button { background: #f2f2f2; color: #000; }
.theme-dark .m-button { background: #666; color: #fff; }
4.5 運(yùn)算
所有數(shù)據(jù)類型均支持相等運(yùn)算 ==
或 !=
雾叭,此外悟耘,每種數(shù)據(jù)類型也有其各自支持的運(yùn)算方式
1. 數(shù)字運(yùn)算
? SassScript 支持?jǐn)?shù)字的運(yùn)算有:
-
數(shù)字的加減乘除、取整等運(yùn)算 (
+, -, *, /, %
)织狐,如果必要會(huì)在不同單位間轉(zhuǎn)換值暂幼。 - 關(guān)系運(yùn)算
<, >, <=, >=
- 可用于所有數(shù)據(jù)類型的相等運(yùn)算 **
==, !=
**
$min-width: 200px;
$max-width: 600px;
// 加減乘除
.border-box {
width: ($max-width / 2) * 3 + $min-width - 10px; // .border-box { width: 1090px; }
}
數(shù)字內(nèi)置函數(shù):
-
percentage($number)
將一個(gè)不帶單位的數(shù)值轉(zhuǎn)成百分比 -
round($number)
將$number
四舍五入為整數(shù),$number
可帶單位 -
ceil($number)
大于$number
移迫,向上取整 -
floor($number)
與ceil()
相反旺嬉,去除$number
小數(shù),向下取整 -
abs($number)
厨埋,返回$number
的絕對(duì)值 -
min($numbers…)
邪媳,返回$number...
的最小值 -
max($numbers…)
,返回$number...
的最大值 -
random([$limit])
荡陷,返回一個(gè)隨機(jī)數(shù)
1.1 除法運(yùn)算
? /
在 CSS 中通常起到分隔數(shù)字的用途雨效,SassScript 作為 CSS 語(yǔ)言的拓展當(dāng)然也支持這個(gè)功能,但是同時(shí)也賦予了 /
除法運(yùn)算的功能废赞。也就是說徽龟,如果 /
在 SassScript 中把兩個(gè)數(shù)字分隔,編譯后的 CSS 文件中也是同樣的作用唉地。 —— 在SassScript中据悔, /
有兩個(gè)作用:分隔數(shù)字、除法運(yùn)算符
以下三種情況 /
將被視為除法運(yùn)算符號(hào):
- 如果值耘沼,或值的一部分极颓,是變量或者函數(shù)的返回值
- 如果值被圓括號(hào)包裹
- 如果值是算數(shù)表達(dá)式的一部分
p {
$width: 1000px;
width: $width/2; // 值的一部分是變量 —— 除法運(yùn)算符
width: round(1.5)/2; // 值是算術(shù)表達(dá)式的一部分 —— 除法運(yùn)算符
height: (500px/2); // 值被圓括號(hào)包裹 —— 除法運(yùn)算符
margin-left: 5px + 8px/2px; // 加減乘除運(yùn)算
}
如果需要使用變量,同時(shí)又要確保 /
不做除法運(yùn)算而是完整地編譯到 CSS 文件中耕拷,只需要用 #{}
插值語(yǔ)句將變量包裹讼昆。
p {
$font-size: 12px;
$line-height: 30px;
font: #{$font-size}/#{$line-height};
}
// 編譯結(jié)果
p { font: 12px/30px; }
2. 顏色值運(yùn)算
? 眾所周知,顏色是由RGB顏色構(gòu)成的骚烧,也就是紅綠藍(lán)。表示顏色的數(shù)據(jù)也是規(guī)則的分段闰围,由紅綠藍(lán)組成赃绊,所以顏色值的運(yùn)算也是分段計(jì)算進(jìn)行的,也就是分別計(jì)算紅色羡榴,綠色碧查,以及藍(lán)色的值:
p {
color: #010203 + #040506;
}
// 計(jì)算 01 + 04 = 05、02 + 05 = 07、03 + 06 = 09忠售,然后編譯為
p { color: #050709; }
數(shù)字與顏色值之間也可以進(jìn)行算數(shù)運(yùn)算传惠,同樣也是分段計(jì)算的,比如
p {
color: #010203 * 2;
}
// 計(jì)算 01 * 2 = 02稻扬、02 * 2 = 04卦方、03 * 2 = 06,然后編譯為
p { color: #020406; }
需要注意的是泰佳,如果顏色值包含 alpha channel(rgba 或 hsla 兩種顏色值)盼砍,必須擁有相等的 alpha 值才能進(jìn)行運(yùn)算,因?yàn)樗阈g(shù)運(yùn)算不會(huì)作用于 alpha 值逝她。
p {
color: rgba(255, 0, 0, 0.75) + rgba(0, 255, 0, 0.75);
}
// 編譯為
p { color: rgba(255, 255, 0, 0.75); }
顏色值的 alpha channel 可以通過 opacify 或 transparentize 兩個(gè)函數(shù)進(jìn)行調(diào)整浇坐。
$trans-red: rgba(255, 0, 0, 0.5);
p {
color: opacify($trans-red, 0.3); // 使用 opacity 函數(shù)
background-color: transparentize($trans-red, 0.25); // 使用 transparentize 函數(shù)
}
// 編譯為
p {
color: rgba(255, 0, 0, 0.8);
background-color: rgba(255, 0, 0, 0.25);
}
IE 濾鏡要求所有的顏色值包含 alpha 層,而且格式必須固定 #AABBCCDD
黔宛,使用 ie_hex_str
函數(shù)可以很容易地將顏色轉(zhuǎn)化為 IE 濾鏡要求的格式近刘。
$trans-red: rgba(255, 0, 0, 0.5);
$green: #00ff00;
div {
filter: progid:DXImageTransform.Microsoft.gradient(enabled='false', startColorstr='#{ie-hex-str($green)}', endColorstr='#{ie-hex-str($trans-red)}');
}
// 編譯為
div {
filter: progid:DXImageTransform.Microsoft.gradient(enabled='false', startColorstr=#FF00FF00, endColorstr=#80FF0000);
}
對(duì)于顏色的操作,scss提供了大量內(nèi)置函數(shù)臀晃,非常方便跌宛。
3. 字符串運(yùn)算
-
+
可用于連接字符串。有引號(hào)字符串+無引號(hào)字符串=有引號(hào)字符串积仗;無引號(hào)字符串+有引號(hào)字符串=無引號(hào)字符串 - 運(yùn)算表達(dá)式與其他值連用時(shí)疆拘,用空格做連接符
- 在有引號(hào)的文本字符串中使用
#{}
插值語(yǔ)句可以添加動(dòng)態(tài)的值 - 空的值被視作插入了空字符串
p {
cursor: e + -resize; // 使用+拼接字符串
margin: 3px + 4px auto; // 運(yùn)算表達(dá)式與其他值連接時(shí),用空格作為連接符
&::before{
content: "Foo " + Bar; // 有引號(hào)字符串+無引號(hào)字符串=有引號(hào)字符串
font-family: sans- + "serif"; //無引號(hào)字符串+有引號(hào)字符串=無引號(hào)字符串
}
&::after{
content: "I ate #{5 + 10} pies!"; // 在有引號(hào)的文本字符串中使用插值語(yǔ)句添加動(dòng)態(tài)的值
}
a{
$value: null;
content: "I ate #{$value} pies!"; // 空的值被視作插入了空字符串
}
}
// 編譯結(jié)果
p { cursor: e-resize; margin: 7px auto; }
p::before { content: "Foo Bar"; font-family: sans-serif; }
p::after { content: "I ate 15 pies!"; }
p a { content: "I ate pies!"; }
字符串內(nèi)置函數(shù)
-
unquote($string)
刪除$string
前后的引號(hào)寂曹。 -
quote($string)
給$string
前后添加引號(hào) -
str-length($string)
返回$string
的長(zhǎng)度 -
str-insert($string, $insert, $index)
在指定位置插入字符 -
str-index($string, $substring)
返回指定字符在字符串的位置 -
to-upper-case($string)
將$string
小寫字母轉(zhuǎn)成大寫字母 -
to-lower-case($string)
將$string
大寫字母轉(zhuǎn)成小寫字母
4. 布爾運(yùn)算
SassScript 支持布爾型的 and
or
以及 not
運(yùn)算哎迄。
5. 數(shù)組運(yùn)算
數(shù)組不支持任何運(yùn)算方式,只能使用 list functions 控制(見數(shù)據(jù)類型——數(shù)組一章)隆圆。
4.6 圓括號(hào)
圓括號(hào)可以用來影響運(yùn)算的順序:
p {
width: 1em + (2em * 3);
}
// 編譯為
p { width: 7em; }
4.7 函數(shù)
SassScript 定義了多種函數(shù)漱挚,有些甚至可以通過普通的 CSS 語(yǔ)句調(diào)用:
p {
color: hsl(0, 100%, 50%); // hsla($hue, $saturation, $lightness, $alpha: 1)
border-width: if(true, 10px, 15px);
}
// p { color: red; border-width: 10px; }
Sass 函數(shù)允許使用關(guān)鍵詞參數(shù) (keyword arguments),上面的例子也可以寫成:
p {
color: hsl($hue: 0, $saturation: 100%, $lightness: 50%);
}
通過 Sass::Script::Functions 查看完整的 Sass 函數(shù)列表渺氧,參數(shù)名旨涝,以及如何自定義函數(shù)。
全局函數(shù)
// hsl函數(shù)--返回值: color
hsl($hue $saturation $lightness)
hsl($hue $saturation $lightness / $alpha)
hsl($hue, $saturation, $lightness, $alpha: 1)
hsla($hue $saturation $lightness)
hsla($hue $saturation $lightness / $alpha)
hsla($hue, $saturation, $lightness, $alpha: 1)
// rgb函數(shù)--返回值: color
rgb($red $green $blue)
rgb($red $green $blue / $alpha)
rgb($red, $green, $blue, $alpha: 1)
rgb($color, $alpha)
rgba($red $green $blue)
rgba($red $green $blue / $alpha)
rgba($red, $green, $blue, $alpha: 1)
rgba($color, $alpha)
// 條件函數(shù)侣背,類似于三元表達(dá)式
if($condition, $if-true, $if-false)
4.8 插值語(yǔ)句 #{} (Interpolation)
插值 (interpolation) —— 將一個(gè)占位符白华,替換成一個(gè)值。插值其實(shí)就是字符串連接的語(yǔ)法糖而已贩耐。
- 通過
#{}
插值語(yǔ)句可以在選擇器或屬性名中使用變量 -
#{}
插值語(yǔ)句也可以在屬性值中插入 SassScript —— 可以避免 Sass 運(yùn)行運(yùn)算表達(dá)式弧腥,直接編譯 CSS。
$name: foo;
$attr: border;
p.#{$name} { // 在選擇器中使用變量
#{$attr}-color: blue; // 在屬性名中使用變量
}
// p.foo { border-color: blue; }
p {
$font-size: 12px;
$line-height: 30px;
font: #{$font-size}/#{$line-height}; // 避免將/用作除法運(yùn)算符
}
// p { font: 12px/30px; }
$colors: (
"primary": tomato,
"secondary": hotpink
);
// _function.scss
@function findColor($key) {
@if map-has-key($map: $colors, $key: $key) {
@return map-get($colors, $key);
}
@warn 'Key `#{$key}` is not found in $colors'; // 插值語(yǔ)句使用場(chǎng)景:打印字符串中變量的內(nèi)容
@return #000;
}
.el {
background-color: findColor(primary2);
}
1. 與css函數(shù)
? 假設(shè)你想基于側(cè)邊欄的寬度設(shè)置主容器的大小潮太。你是一個(gè)勤奮的前端開發(fā)者管搪,已經(jīng)把這個(gè)寬度存儲(chǔ)在一個(gè)變量中虾攻,所以,你可能會(huì)這樣做:
$sidebar-width: 250px;
.main {
width: calc(100% - $sidebar-width); //將變量用于css函數(shù)--初衷是想像css那樣進(jìn)行運(yùn)算更鲁,但是霎箍。。
}
// 編譯結(jié)果: .main { width: calc(100% - $sidebar-width); }
? 然后澡为,你會(huì)驚訝地發(fā)現(xiàn)漂坏,根本不work。沒有報(bào)錯(cuò)缀壤,容器的大小卻又不正確樊拓。如果你去審查你的dom元素,你會(huì)看到這個(gè)被劃掉了塘慕。因?yàn)榻钕模@是不合法的。
? 現(xiàn)在我們應(yīng)該想到:calc()
是一個(gè)CSS函數(shù)图呢,不是一個(gè)Sass函數(shù)条篷。這就是說Sass會(huì)將整個(gè)表達(dá)式解釋成一個(gè)字符串。你可以試試:
$sidebar-width: 250px;
.main {
$type-of-expression: type-of(calc(100% - $sidebar-width)); // 使用type-of判斷類型
content: $type-of-expression;
}
// .main { content: string; }
? 因?yàn)檫@是一個(gè)字符串蛤织,難怪Sass表現(xiàn)和之前@warn
中的$colors
字符串一樣赴叹。$sidebar-width
被認(rèn)為是一個(gè)常規(guī)字符串,所以打出來就是它自己指蚜。但這都不是我們所想要的乞巧,是吧?我們用插值這樣做摊鸡。
.main {
width: calc(100% - #{$sidebar-width}); // 在編譯時(shí)绽媒,會(huì)用250px替換#{$sidebar-width}
}
// 編譯后:.main { width: calc(100% - 250px); }
我們僅僅在這里談了calc()
,但其實(shí)和其他CSS 原生函數(shù)是一樣的免猾,包括偽類是辕。比如:url()
,linear-gradient()
猎提,radial-gradient()
获三,cubic-bezier()
。
以下是另一個(gè)使用CSS函數(shù)的例子:
@for $i from 1 through $max {
.el:nth-of-type(#{$i}) {
// ...
}
}
小結(jié):Sass會(huì)把CSS函數(shù)認(rèn)為是字符串锨苏,所以想要在最后獲得它們的值疙教,要求你轉(zhuǎn)義所有同它們一起使用的變量。
2. css指令
我們將視轉(zhuǎn)移到另一個(gè)有趣的變量插值場(chǎng)景:CSS指令蚓炬,比如@support
松逊,@page
,最重要的還是@media
肯夏。
現(xiàn)在,Sass是怎樣解析CSS指令,尤其是demia指令的驯击。我已經(jīng)查看過Sass的源碼烁兰,當(dāng)我Ruby環(huán)境有點(diǎn)問題的時(shí)候,我找到一些有趣的事情徊都。
def query_expr
interp = interpolation
return interp if interp
return unless tok(/\(/)
res = ['(']
ss
res << sass_script(:parse)
if tok(/:/)
res << ': '
ss
res << sass_script(:parse)
end
res << tok!(/\)/)
ss
res
end
第一行告訴Sass沪斟,如果有一個(gè)插值表達(dá)式的話,便返回media query
暇矫。如果找到一個(gè)開括號(hào)((
)主之,便會(huì)一直往下走,解析所有的東西李根,反之就會(huì)拋出一個(gè)錯(cuò)誤槽奕。我們?cè)谶@里試試一個(gè)例子:
$value: screen;
@media $value {
// ...
}
毫不驚訝的是,這失敗了:
Invalid CSS after "@media ": expected media query (e.g. print, screen, print and screen), was "$value {"
就像錯(cuò)誤信息提示的那樣房轿,它期待一個(gè)media query粤攒。在這里,如果你的變量在 @media
字符串后面囱持,需要使用插值才可以夯接。比如:
$value: screen;
@media #{$value} {
// ...
}
和我們之前討論的Ruby轉(zhuǎn)義規(guī)則一樣,如果@media
后面緊跟(()
)纷妆,你就不再需要插值變量了盔几,因?yàn)镾ass會(huì)求出所有在這些括號(hào)里面的值。比如:
$value: 1336px;
@media (max-width: $value) {
// ...
}
在這個(gè)示例中掩幢,Sass將這個(gè)表達(dá)式(max-width: $value)
轉(zhuǎn)化成(max-width: 1337px)
逊拍,最后生成合法的CSS結(jié)果。所以粒蜈,我們便沒有必要再對(duì)變量轉(zhuǎn)義了顺献。
4.9 & in SassScript
? 就像在選擇器中使用一樣,在SassScript
中 &
表示當(dāng)前的父選擇器枯怖,它時(shí)一個(gè)用逗號(hào)分隔的數(shù)組列表
.foo.bar .baz.bang, .bip.qux {
$selector: &; // 定義一個(gè)變量注整,變量值就是 父選擇器標(biāo)識(shí)符
content: $selector;
}
// 編譯結(jié)果
.foo.bar .baz.bang, .bip.qux {
content: .foo.bar .baz.bang, .bip.qux; // 是一個(gè)用逗號(hào)分隔的數(shù)組列表
}
如果不存在父選擇器,那么 & 的值就是 null度硝,這也就意味著可以在 mixin中去判父元素是否存在:
@mixin does-parent-exist {
@if & { // 如果父選擇器存在肿轨,那么就給父元素添加hover樣式
&:hover {
color: red;
}
} @else {
a {
color: red;
}
}
}
div{ @include does-parent-exist(); }
// 編譯結(jié)果 div:hover { color: red; }
4.10 變量定義 !default
? 可以在變量的結(jié)尾添加 !default
,給一個(gè)未通過 !default
聲明賦值的變量賦值蕊程,此時(shí)椒袍,如果變量已經(jīng)被賦值,不會(huì)再被重新賦值藻茂,但是如果變量還沒有被賦值驹暑,則會(huì)被賦予新的值玫恳。
變量是 null 空值時(shí)將視為未被 !default
賦值。
$content: "First content";
$content: "Second content" !default; // $content在此之前已經(jīng)被賦值优俘,所以此處不會(huì)進(jìn)行重新賦值
$new_content: null; // 變量值null被視為未賦值
$new_content: "First time reference" !default; // 所以此處可以重新賦值
#main {
content: $content;
new-content: $new_content;
}
// 編譯結(jié)果
#main { content: "First content"; new-content: "First time reference"; }
!default一個(gè)重要的作用就是京办,如果我們引入的他人scss文件中的變量有默認(rèn)值的設(shè)置,那么我們就可以很靈活的來修改這些默認(rèn)值帆焕,只要在這些導(dǎo)入文件之前引入就一個(gè)配置scss文件即可,而無需修改他人的scss文件惭婿,例如:
// 在導(dǎo)入他人文件之前,修改默認(rèn)值叶雹,而無需修改他人的scss文件
$theme: dark;
// 引入他人的scss文件
@import "config";
@import "variables";
@import "mixins";