Sass學(xué)習(xí)筆記1 - 基礎(chǔ)篇

CSS預(yù)處理器 —— Sass學(xué)習(xí)筆記(基礎(chǔ))

參考

一、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)

  1. 這種格式以 .scss 作為拓展名
  2. 這種格式僅在 CSS3 語(yǔ)法的基礎(chǔ)上進(jìn)行拓展牺陶,所有 CSS3 語(yǔ)法在 SCSS 中都是通用的,同時(shí)加入 Sass 的特色功能梳猪。
  3. SCSS 也支持大多數(shù) CSS hacks 寫法以及瀏覽器前綴寫法 (vendor-specific syntax)逃呼,以及早期的 IE 濾鏡寫法。

另一種也是最早的 Sass 語(yǔ)法格式

  1. 被稱為縮進(jìn)格式 (Indented Sass) 隙姿,通常簡(jiǎn)稱 "Sass"奈嘿,是一種簡(jiǎn)化格式掺冠。
  2. 這種格式以 .sass 作為拓展名
  3. 它使用 <u>“縮進(jìn)” 代替 “花括號(hào)” 表示屬性屬于某個(gè)選擇器</u>憾股,用 <u>“換行” 代替 “分號(hào)” 分隔屬性</u>婉商,很多人認(rèn)為這樣做比 SCSS 更容易閱讀肠牲,書寫也更快速。
  4. 縮進(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)境變量蜘矢。如下圖:

01-install ruby.jpg

? 安裝完成后需測(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)來 輕松地安裝SassCompass米死。要安裝最新版本的SassCompass材蹬,你需要輸入下面的命令:

# 安裝如下(如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 軟件方式編譯
  1. 推薦國(guó)產(chǎn)免費(fèi)圖形編譯工具 Koala
  2. 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 :hoverarticle元素內(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.containerh1月幌、.containerh2.containerh3分別組合悬蔽,然后將三者重新組合成一個(gè)群組選擇器扯躺。然后對(duì)于內(nèi)嵌在群組選擇器內(nèi)的嵌 套規(guī)則,處理方式也一樣蝎困,將.container h1a录语、.container h2a.container h3a再分別組合禾乘,然后重新組合成一個(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í)變量纲堵。改成是多半因?yàn)閌!highlight-color`看起來太丑了),比如`highlight-colorsidebar-width`闰渔。為什么選擇`符號(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; 
  1. 任何可以用作css屬性值的賦值都可以用作sass的變量值妈踊。
  2. 變量聲明后還未生效,只有當(dāng)變量被引用后才生效
  3. 在聲明變量時(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 的背景色不一樣。

02-variable-array.png

用傳統(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 2px5px 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 () 3px1px 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 可以通過 opacifytransparentize 兩個(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";
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末财饥,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子折晦,更是在濱河造成了極大的恐慌钥星,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,290評(píng)論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件筋遭,死亡現(xiàn)場(chǎng)離奇詭異打颤,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)漓滔,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,107評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門编饺,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人响驴,你說我怎么就攤上這事透且。” “怎么了豁鲤?”我有些...
    開封第一講書人閱讀 156,872評(píng)論 0 347
  • 文/不壞的土叔 我叫張陵秽誊,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我琳骡,道長(zhǎng)锅论,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,415評(píng)論 1 283
  • 正文 為了忘掉前任楣号,我火速辦了婚禮最易,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘炫狱。我一直安慰自己藻懒,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,453評(píng)論 6 385
  • 文/花漫 我一把揭開白布视译。 她就那樣靜靜地躺著嬉荆,像睡著了一般。 火紅的嫁衣襯著肌膚如雪酷含。 梳的紋絲不亂的頭發(fā)上鄙早,一...
    開封第一講書人閱讀 49,784評(píng)論 1 290
  • 那天汪茧,我揣著相機(jī)與錄音,去河邊找鬼蝶锋。 笑死陆爽,一個(gè)胖子當(dāng)著我的面吹牛什往,可吹牛的內(nèi)容都是我干的扳缕。 我是一名探鬼主播,決...
    沈念sama閱讀 38,927評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼别威,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼躯舔!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起省古,我...
    開封第一講書人閱讀 37,691評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤粥庄,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后豺妓,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體惜互,經(jīng)...
    沈念sama閱讀 44,137評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,472評(píng)論 2 326
  • 正文 我和宋清朗相戀三年琳拭,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了训堆。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,622評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡白嘁,死狀恐怖坑鱼,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情絮缅,我是刑警寧澤鲁沥,帶...
    沈念sama閱讀 34,289評(píng)論 4 329
  • 正文 年R本政府宣布,位于F島的核電站耕魄,受9級(jí)特大地震影響画恰,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜吸奴,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,887評(píng)論 3 312
  • 文/蒙蒙 一允扇、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧奄抽,春花似錦蔼两、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至档泽,卻和暖如春俊戳,著一層夾襖步出監(jiān)牢的瞬間揖赴,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評(píng)論 1 265
  • 我被黑心中介騙來泰國(guó)打工抑胎, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留燥滑,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,316評(píng)論 2 360
  • 正文 我出身青樓阿逃,卻偏偏與公主長(zhǎng)得像铭拧,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子恃锉,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,490評(píng)論 2 348