一、Sass的語法格式及編譯調(diào)試
1. Sass和scss的區(qū)別
本質(zhì)上來說是同一個(gè)東西,只是語法上有細(xì)微的差異:
現(xiàn)有一段基礎(chǔ)CSS代碼:
body {
font: 100% Helvetica, sans-serif;
color: #333;
}
使用Sass語法編譯如下:
$font-stack: Helvetica, sans-serif
$primary-color: #333
body
font: 100% $font-stack
color: $primary-color
Sass 語法是 Sass 的最初語法格式,他是通過 tab 鍵控制縮進(jìn)的一種語法規(guī)則,而且這種縮進(jìn)要求非常嚴(yán)格。另外其不帶有任何的分號(hào)和大括號(hào)。常常把這種格式稱為 Sass 老版本,其文件名以“.sass”為擴(kuò)展名。
使用Scss語法編譯如下:
$fon-stack: Helvetica,sans-serif;
$primary-color: #333;
body{
font: 100% $font-stack;
color: $primary-color;
}
SCSS 是 Sass 的新語法格式,從外形上來判斷他和 CSS 長(zhǎng)得幾乎是一模一樣,代碼都包裹在一對(duì)大括號(hào)里,并且末尾結(jié)束處都有一個(gè)分號(hào)。其文件名格式常常以“.scss”為擴(kuò)展名。
2. Sass 編譯
在項(xiàng)目中還是引用“.css”文件,Sass 只不過是做為一個(gè)預(yù)處理工具,提前幫你做事情,只有你需要時(shí)候,他才有攻效。所以Sass 的編譯 就出現(xiàn)了。因?yàn)?Sass 開發(fā)之后,要讓 Web 頁面能調(diào)用 Sass 寫好的東西,就得有這么一個(gè)過程,這個(gè)過程就稱之為 Sass 編譯過程。Sass 的編譯有多種方法:
- 命令編譯
- GUI工具編譯
- 自動(dòng)化編譯
2.1 Sass命令編譯
- 單文件編譯:↓
sass sass/style.scss:css/style.css
- 多文件編譯:↓
sass sass/:css/
上面的命令表示將項(xiàng)目中“sass”文件夾中所有“.scss”(“.sass”)文件編譯成“.css”文件,并且將這些 CSS 文件都放在項(xiàng)目中“css”文件夾中。
- 監(jiān)測(cè)代碼變化,實(shí)時(shí)編譯:↓
sass --watch sass/style.scss: css/style.css

一旦我的 sacc/style.scss 文件有任何修改,只要我重新保存了修改的文件,命令終端就能監(jiān)測(cè),并重新編譯出文件。
2.2 Sass GUI工具編譯
實(shí)用性完全比不上命令行,我直接跳過了。
2.3 Sass 自動(dòng)化編譯
現(xiàn)在還不會(huì)用,留著后面來看。
- Grunt 配置 Sass編譯的示例代碼:↓
module.exports = function(grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
sass: {
dist: {
files: {
'style/style.css' : 'sass/style.scss'
}
}
},
watch: {
css: {
files: '**/*.scss',
tasks: ['sass']
}
}
});
grunt.loadNpmTasks('grunt-contrib-sass');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.registerTask('default',['watch']);
}
- Gulp 配置 Sass 編譯的示例代碼:↓
var gulp = require('gulp');
var sass = require('gulp-sass');
gulp.task('sass', function () {
gulp.src('./scss/*.scss')
.pipe(sass())
.pipe(gulp.dest('./css'));
});
gulp.task('watch', function() {
gulp.watch('scss/*.scss', ['sass']);
});
gulp.task('default', ['sass','watch']);
3. [Sass]不同樣式風(fēng)格的輸出方法
3.1 [Sass]嵌套輸出方式 nested
例如這樣一段sass:
$bg-color: #f0f0f0;
$red-color: #ff5050;
.nav {
background-color: $bg-color;
ul {
margin: 0;
padding: 0;
list-style: none;
}
li { display: inline-block; }
a {
display: block;
padding: 6px 12px;
text-decoration: none;
color: $red-color;
}
}
這段代碼在編譯的時(shí)候需要帶上參數(shù):--style nested (默認(rèn)以這個(gè)參數(shù)編譯)↓
sass --watch sass/style.scss:css/style.css --style nested
編譯以后的css樣式如下:↓
.nav {
background-color: #f0f0f0; }
.nav ul {
margin: 0;
padding: 0;
list-style: none; }
.nav li {
display: inline-block; }
.nav a {
display: block;
padding: 6px 12px;
text-decoration: none;
color: #ff5050; }

3.2 [Sass]展開輸出方式 expanded
這個(gè)輸出的 CSS 樣式風(fēng)格和 nested 類似,只是大括號(hào)在另起一行,同樣上面的代碼,在編譯時(shí)需要帶參數(shù)--style expanded,
sass --watch sass/style.scss:css/style.css --style expanded
編譯出來:↓
.nav{
background-color: #f0f0f0;
}
.nav ul {
margin: 0;
padding: 0;
list-style: none;
}
.nav li {
display: inline-block;
}
.nav a {
display: block;
padding: 6px 12px;
text-decoration: none;
}

3.3 [Sass]緊湊輸出方式 compact
在編譯的時(shí)候帶上參數(shù)--style compact:
sass --watch sass/style.scss:css/style.css --style compact
編譯出來:↓
.nav { background-color: #f0f0f0; }
.nav ul { margin: 0; padding: 0; list-style: none; }
.nav li { display: inline-block; }
.nav a { display: block; padding: 6px 12px; text-decoration: none; color: #ff5050; }

3.4 [Sass]壓縮輸出方式 compressed
在編譯的時(shí)候帶上參數(shù) --style compressed:
sass --watch sass/style.scss:css/style.css --style compressed
壓縮輸出方式會(huì)去掉標(biāo)準(zhǔn)的 Sass 和 CSS 注釋及空格。也就是壓縮好的 CSS 代碼樣式風(fēng)格:↓
.nav{background-color:#f0f0f0}.nav ul{margin:0;padding:0;list-style:none}.nav li{display:inline-block}.nav a{display:block;padding:6px 12px;text-decoration:none;color:#ff5050}

3.5 [Sass]的調(diào)試
在Chrome的開發(fā)者工具中找到Sources,在這里的修改可以及時(shí)得到反饋,和在websorem里面操作一樣,保存一次編譯一次。

二、Sass的基本特性-基礎(chǔ)
1、聲明變量

上圖非常清楚告訴了大家,Sass 的變量包括三個(gè)部分:
- 聲明變量的符號(hào)“$”
- 變量名稱
- 賦予變量的值
Bootstrap Sass版本定義primary-button的方法:↓
$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;
2、普通變量與默認(rèn)變量
- 普通變量:
定義之后可以在全局使用:↓
$fontSize: 14px;
body{
font-size: $fontSize;
}
編譯后的代碼:↓
body{font-size:14px;}
- 默認(rèn)變量:
sass 的默認(rèn)變量?jī)H需要在值后面加上!default即可。
$baseLineHeight: 1.5 !default;
body{
line-height: $baseLineHeight;
}
編譯后的代碼:↓
body{line-height:1.5;}
覆蓋默認(rèn)樣式:只需要在默認(rèn)變量之前重新聲明下變量即可 ↓
$baseLineHeight: 2;
$baseLineHeight: 1.5 !default;
body{
line-height: $baseLineHeight;
}
編譯后的代碼:↓
body{line-height:2;}
默認(rèn)變量的價(jià)值在進(jìn)行組件化開發(fā)的時(shí)候會(huì)非常有用。
3、變量的調(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,4%) !default;
調(diào)用:
.btn-primary{
background-color: $btn-primary-bg;
color: $btn-primary-color;
border: 1px solid $btn-primary-border;
}
編譯出來的CSS:
.btn-primary{
background-color: #337ab7;
color: #fff;
border: 1px solid #2e6da4;
}
4、局部變量和全局變量
- 全局變量與局部變量
示例:
$color: orange !default; //定義全局變量(在選擇器、函數(shù)、混合宏...的外面定義的變量為全局變量)
.block
color: $color; //調(diào)用全局變量
}
em{
$color: red; //定義局部變量
a {
color: $color; //調(diào)用局部變量
}
}
span{
color: $color; //調(diào)用全局變量
}
css編譯結(jié)果:↓
.block{color: orange;}
em a{color: red;}
span{color: orange;}
可以得知,在元素內(nèi)部定義的變量不會(huì)影響其他元素。示例中寫在元素外部的變量:$color: orange !default;是一個(gè)全局變量;而寫在元素內(nèi)部的變量:$color:orange !default;就是一個(gè)局部變量。
- 全局變量的影子
當(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í)候聲明變量?
滿足所有下述標(biāo)準(zhǔn)時(shí)方可創(chuàng)建新變量:
- 該值至少重復(fù)出現(xiàn)了兩次;
- 該值至少可能會(huì)被更新一次;
- 該值所有的表現(xiàn)都與變量有關(guān)(非巧合)。
基本上,沒有理由聲明一個(gè)永遠(yuǎn)不需要更新或者只在單一地方使用變量。
5、Sass嵌套
5.1 選擇器嵌套
例如有這樣的html結(jié)構(gòu):
<header>
<nav>
<a href=“##”>Home</a>
<a href=“##”>About</a>
<a href=“##”>Blog</a>
</nav>
<header>
使用sass 方法選中header中的a標(biāo)簽:
nav{
a{
color: red;
header &{
coloe: green;
}
}
}
連體符 & 使用方法,編譯結(jié)果:↓
nav a {
color: red;
}
header nav a {
color: green;
}
5.2 屬性嵌套
CSS 有一些屬性前綴相同,只是后綴不一樣,比如:border-top/border-right,與這個(gè)類似的還有 margin、padding、font 等屬性。假設(shè)你的樣式中用到了:
.box{
border-top: 1px solid red;
border-bottom: 1px solid green;
}
在Sass中我們可以這樣寫:
.box{
border: { //這里border后面的" : "是關(guān)鍵;
top: 1px solid red;
bottom: 1px solid green;
}
}
5.3 偽類嵌套
其實(shí)偽類嵌套和屬性嵌套非常類似,只不過他需要借助&符號(hào)一起配合使用。我們就拿經(jīng)典的“clearfix”為例吧:↓
.clearfix{
&:before,&:after{
content:"";
display: table;
}
&:after{
clear: both;
overflow: hidden;
}
}
編譯后的代碼:↓
.clearfix:before, .clearfix:after {
content: "";
display: table;
}
.clearfix:after {
clear: both;
overflow: hidden;
}
避免選擇器嵌套:
選擇器嵌套最大的問題是將使最終的代碼難以閱讀。開發(fā)者需要花費(fèi)巨大精力計(jì)算不同縮進(jìn)級(jí)別下的選擇器具體的表現(xiàn)效果。
選擇器越具體則聲明語句越冗長(zhǎng),而且對(duì)最近選擇器的引用(&)也越頻繁。在某些時(shí)候,出現(xiàn)混淆選擇器路徑和探索下一級(jí)選擇器的錯(cuò)誤率很高,這非常不值得。
為了防止此類情況,我們應(yīng)該盡可能避免選擇器嵌套。然而,顯然只有少數(shù)情況適應(yīng)這一措施。
6、混合宏
當(dāng)頁面樣式越來越復(fù)雜,需要重復(fù)使用大段的樣式時(shí),就需要使用混合宏。
6.1 聲明混合宏
- 不帶參數(shù)的混合宏
在Sass中使用@mixin來聲明一個(gè)混合宏,如:↓
@mixin border-radius{
-webkit-border-radius: 5px;
border-radius: 5px;
}
其中 @mixin 是用來聲明混合宏的關(guān)鍵詞,有點(diǎn)類似 CSS 中的 @media、@font-face 一樣。border-radius 是混合宏的名稱。大括號(hào)里面是復(fù)用的樣式代碼。
- 帶參數(shù)的混合宏
除了聲明一個(gè)不帶參數(shù)的混合宏之外,還可以在定義混合宏時(shí)帶有參數(shù),如:↓
@mixin border-radius($radius:5px){
-webkit-border-radius: $radius;
border-radius: $radius;
}
- 復(fù)雜的混合宏
可以在大括號(hào)里面寫上帶有邏輯關(guān)系,幫助更好的做你想做的事情,如:↓
@mixin box-shaow($shadow...){
@if length($shadow) >= 1{
@include prefixer(box-shadow,$shadow);
}@else{
$shadow: 0 0 4px rgba(0,0,0,.3);
@include prefixer(box-shdow,$shadow);
}
}
這個(gè) box-shadow 的混合宏,帶有多個(gè)參數(shù),這個(gè)時(shí)候可以使用“ … ”來替代。簡(jiǎn)單的解釋一下,當(dāng) $shadow 的參數(shù)數(shù)量值大于或等于“ 1 ”時(shí),表示有多個(gè)陰影值,反之調(diào)用默認(rèn)的參數(shù)值“ 0 0 4px rgba(0,0,0,.3) ”。
6.2 調(diào)用混合宏
關(guān)鍵詞@include來調(diào)用聲明好的混合宏。例如在你的樣式中定義了一個(gè)圓角的混合宏“border-radius”:↓
@mixin border-radius{
-webkit-border-radius: 3px;
border-radius: 3px;
}
在一個(gè)按鈕中要調(diào)用定義好的混合宏“border-radius”,可以這樣使用:↓
button{
@include border-radius;
}
編譯后的CSS如下:↓
button {
-webkit-border-radius: 10px;
border-radius: 10px
}

6.3 混合宏的參數(shù)
- 傳一個(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”。編譯后的CSS:↓
.box {
-webkit-border-radius: 3px;
border-radius: 3px;
}
- 傳一個(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è)你的頁面中的圓角很多地方都是“3px”的圓角,那么這個(gè)時(shí)候只需要調(diào)用默認(rèn)的混合宏“border-radius”:↓
.btn{
@include border-radius;
}
編譯出來的CSS:
.btn{
-webkit-border-radius: 3px;
border-radius: 3px;
}
但有的時(shí)候,頁面中有些元素的圓角值不一樣,那么可以隨機(jī)給混合宏傳值,如:↓
.box{
@include border-radius(50%);
}
新的值"50%"會(huì)覆蓋原有的值“3px”,編譯后的CSS:
.box{
-webkit-border-radius:50%;
border-radius:50%;
}
- 傳多個(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;
padding-left: -($width)/2;
}
在混合宏“center”就傳了多個(gè)參數(shù)。在實(shí)際調(diào)用和其他混合宏是一樣的:↓
.box-center{
@include center(500px,300px)
}
編譯后的CSS:
.box-center {
width: 500px;
height: 300px;
position: absolute;
top: 50%;
left: 50%;
margin-top: -150px;
padding-left: -250px;
}
有一個(gè)特別的參數(shù)“...”。當(dāng)混合宏的參數(shù)過多之時(shí),可以使用參數(shù)來替代,如:↓
@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;
}
}
在調(diào)用時(shí)傳參:↓
.box {
@include box-shadow(0 0 1px rgba(#000,.5), 0 0 2px rgba(#000,.2));
}
編譯出來的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);
}
- 混合宏的不足
最大的不足之處是會(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”混合宏。先來看編譯出來的 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 的混合宏最不足之處。
6.4 sass 擴(kuò)展/繼承
- 繼承@extend
.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;
}
編譯后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 中的繼承,可以繼承類樣式塊中所有樣式代碼,而且編譯出來的 CSS 會(huì)將選擇器合并在一起,形成組合選擇器。
6.5 [Sass]占位符 %placeholder
Sass中的占位符%placeholder功能很強(qiáng)。它可以取代以前CSS中的基類造成的代碼冗余:%placeholder聲明的代碼,如果不被@extend調(diào)用的話,不會(huì)產(chǎn)生任何代碼。示例:
%mt5{
margin-top: 5px;
}
%pt5{
padding-top: 5px;
}
這段代碼如果沒有被@extend調(diào)用,不會(huì)產(chǎn)生任何代碼塊。只有通過@extend調(diào)用才會(huì)產(chǎn)生代碼:↓
.btn {
@extend %mt5;
@extend %pt5;
}
.block {
@extend %mt5;
span {
@extend %pt5;
}
}
編譯后的CSS:↓
.btn, .block {
margin-top: 5px;
}
.btn, .block span {
padding-top: 5px;
}
由上可知,用過@extend調(diào)用的占位符,編譯出來的代碼會(huì)將相同的代碼合并在一起。這一點(diǎn)非常棒!
6.6 [Sass]混合宏 VS 繼承 VS 占位符
三者如何選擇,才能發(fā)揮各自最佳優(yōu)勢(shì)?
-
混合宏的使用
混合宏.png
缺點(diǎn):通過編譯出來的CSS可以看出,混合宏不會(huì)自動(dòng)合并相同的樣式代碼margin-top:5px;,這樣極易造成代碼冗余。
優(yōu)點(diǎn):可以傳參。
總結(jié):如果代碼塊中涉及到變量,建議使用混合宏來創(chuàng)建相同的代碼塊。
-
繼承
Sass 繼承.png
繼承編譯出來的代碼會(huì)將使用繼承的代碼塊合并到一起,通過組合選擇器的方式展現(xiàn):
.mt, .block, .block span, .header, .header span {
margin-top: 5px;
}
缺點(diǎn):不能傳參。
優(yōu)點(diǎn):代碼干凈不冗余。
總結(jié):如果代碼塊不需要任何傳參,而且有一個(gè)基類已經(jīng)存在文件中,建議使用Sass的繼承。
- 占位符
占位符.png
對(duì)比繼承和占位符,編譯后的CSS基本一致,只是繼承的代碼塊中生成了.mt的選擇器,而占位符沒有。那么就是說二者的主要區(qū)別是:
占位符是獨(dú)立定義的,不調(diào)用不會(huì)產(chǎn)任何代碼;
繼承是首先由一個(gè)基類存在.mt,不管調(diào)用與否,基類樣式都會(huì)被編譯出來。

7、Sass插值 #{}
想寫一個(gè)更干凈的、高效的和面向?qū)ο蟮腃SS。Sass中的插值(interpolation)就是重要的一部分。示例:
$space:(margin,padding);
@mixin set-value($side,$value){
@each $prop in $space{
#{$prop}-#{side}: $value;
}
}
.container{
@include set-value(top,20px);
}
它可以讓變量和屬性工作的很完美,編譯后的CSS:
.container {
margin-top: 20px;
padding-top: 20px;
}
當(dāng)你想設(shè)置屬性值的時(shí)候你可以使用字符串插入進(jìn)來。另一個(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)
編譯之后:
.header-text-small {
font-size: 12px;
}
.header-text-medium {
font-size: 20px;
}
.header-text-big {
font-size: 40px;
}
8. 注釋
sass有兩種注釋方式:
- 類似CSS注釋:
/* 這里是注釋 */ - 類似JS注釋:
//這里是注釋
區(qū)別是,/* */會(huì)在編譯的CSS中顯示,//在編譯的CSS里不顯示。示例:
//定義占位符
%mt5{
margin-top: 50px;
}
/*調(diào)用一個(gè)函數(shù)*/
.box{
@extend %mt5
}
編譯后:
.box {
margin-top: 5px;
}
/*調(diào)用一個(gè)占位符*/
9. 數(shù)據(jù)類型
sass中包含以下幾種數(shù)據(jù)類型:
- 數(shù)字:如1、2、3、10px;
- 字符串:有引號(hào)字符串或無引號(hào)字符串,如,“foo”、‘bar’、baz;
- 顏色:blue、#ff5050、rgba(255,180,20,0.3);
- 布爾值:true、false;
- 空值:null;
- 值列表:用空格或者逗號(hào)分開,如:1.5em 1em 0 2em 、Helvetice,Arial,sans-serif
10. 字符串
SassScript支持CSS的兩種字符串類型:
- 有引號(hào)的字符串:“Lucida Grande”、‘http://sass-lang.com’;
- 無引號(hào)的字符串:sans-serifbold。
在CSS編譯時(shí)不會(huì)改變其類型,只有使用插值#{}時(shí),有引號(hào)字符串將被編譯為無引號(hào)字符串,這樣方便了在混合宏中引用選擇器名:
@mixin firefox-message($selector){
body.firefox #{$selector}:before{
content: "Hi,Firefox users!"
}
}
@include firefox-message(".header")
編譯為:
body.firefox .header:before{
content: "Hi,firefox user!";
}
11. 值列表
所謂值列表,是指sass如何處理CSS中 margin: 10px 15px 0 0 或者 font-face: Helvetica, Arial,sans-serif 這種通過空格或者逗號(hào)分割的一系列值。
獨(dú)立的值被視為只包含一個(gè)值的值列表。
Sass列表函數(shù)(Sass list functions)賦予了值列表更多功能(Sass進(jìn)級(jí)會(huì)有講解):
- nth函數(shù)(nth function) 可以直接訪問值列表中的某一項(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)層,所以也可以寫成 (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。
三、Sass的基本特性-運(yùn)算
程序中的運(yùn)算是常見的一件事情,但在 CSS 中能做運(yùn)算的,到目前為止僅有 calc() 函數(shù)可行。但在 Sass 中,運(yùn)算只是其基本特性之一。
3.1 加法
在變量或?qū)傩灾卸伎梢宰黾臃ㄟ\(yùn)算:
.container{
width: 20px + 8in; //1in = 2.54cm = 25.4 mm = 72pt = 6pc = 96px
height: 8in + 20px; //按第一個(gè)值得單位計(jì)算
}
點(diǎn)這里查看關(guān)于單位in的 單位in的定義
編譯后:
.container{
width: 788px;
height: 8.20833in;
}
單對(duì)于不同類型的單位是,在sass中計(jì)算會(huì)報(bào)錯(cuò)。如下所示:
.container{
width: 20px + 1em;
}
報(bào)錯(cuò):”Incompatible units: 'em' and ‘px'. “
in mm cm pt pc px等單位都能運(yùn)算,ex em rem等相對(duì)于當(dāng)前字體的單位不能運(yùn)算。

3.2 減法
示例:
$full-width: 960px;
$sidebar-width: 200px;
.content{
width:{
$full-width - $siderbar-width;
}
}
編譯的CSS代碼:
.content{
width: 760px;
}
在遇到不同單位時(shí),編譯也會(huì)報(bào)錯(cuò)。
3.3 乘法
Sass中乘法運(yùn)算和加減法運(yùn)算略有不同,當(dāng)一個(gè)單位同時(shí)聲明兩個(gè)值時(shí)會(huì)有問題。比如:

在乘法運(yùn)算時(shí),兩個(gè)值的單位相同時(shí),只需要為一個(gè)數(shù)值提供單位即可:

不同類型的單位進(jìn)行乘法運(yùn)算時(shí)也會(huì)報(bào)錯(cuò):

實(shí)例:@for循環(huán)讓icon圖標(biāo)的background-position的Y軸值按20px遞減:

3.4 除法
Sass的乘法運(yùn)算規(guī)則也適用于除法運(yùn)算,但還有一個(gè)特殊之處。CSS中”/“作為一個(gè)符號(hào)出現(xiàn),因此在sass直接使用”/“作為除號(hào),編譯時(shí)即得不到我們需要的結(jié)果,也不會(huì)報(bào)錯(cuò),比如:
.container{
width: 100px / 2;
}
編譯后的CSS:
.container{
width: 100px / 2;
}
修正這個(gè)問題只需要給運(yùn)算外面添加一個(gè)小括號(hào)( )即可:
.container{
width: (100px / 2);
}
編譯后的CSS:
.container{
width: 50px;
}
另外還有其他的情況” / “符號(hào)被當(dāng)做除法運(yùn)算:
- 如果數(shù)值或它的任意部分是存儲(chǔ)在一個(gè)變量中,或是函數(shù)返回值。
- 如果數(shù)值被圓括號(hào)包圍
- 如果數(shù)值是另外一個(gè)數(shù)學(xué)表達(dá)式的一部分。
p {
font: 10px/8px; // 純 CSS,不是除法運(yùn)算
$width: 1000px;
width: $width/2; // 使用了變量,是除法運(yùn)算
width: round(1.5)/2; // 使用了函數(shù),是除法運(yùn)算
height: (500px/2); // 使用了圓括號(hào),是除法運(yùn)算
margin-left: 5px + 8px/2px; // 使用了加(+)號(hào),是除法運(yùn)算
}
3.5 變量計(jì)算
示例:
$content-width: 720px;
$sidebar-width: 220px;
$gutter:20px;
.container{
width: $content-width + $sidebar-width + $gutter;
margin: 0 auto;
}
編譯結(jié)果:
.container {
width: 960px;
margin: 0 auto;
}
3.6 數(shù)字運(yùn)算
計(jì)算 Grid 單列列寬的運(yùn)算示例:
.container{
width: ((220px + 720px) - 11 * 20) / 12;
}
編譯結(jié)果:
.container{
width: 60px;
}
3.7 顏色運(yùn)算
所有算數(shù)運(yùn)算都支持顏色值,并且是分段運(yùn)算的,也就是說,紅、綠和藍(lán)各顏色分段進(jìn)行運(yùn)算。如:
p{
color: #010203 + #040506;
}
計(jì)算方式:#( 01+04)(02+05)(03+06),編譯后的CSS:
p{
color: #050709;
}
也可以是數(shù)字和顏色值一起運(yùn)算,同樣也是分段運(yùn)算,例如:
p{
color: #010203 * 2
}
計(jì)算方式為:#(012)(022)(03*2),編譯后的CSS:
p{
color: #020406
}
3.8字符運(yùn)算
- Sass中可以通過”+“來對(duì)字符串進(jìn)行連接,和JS類似:
$content: "Hello" + " " + "Sass!";
.box: before{
content: " #{$content}";
}
編譯出來的CSS:
.box{
content:"Hello Sass"
}
- 連接字符
div{
cursor: e + -resize;
}
編譯后CSS:
div{
cursor: e-resize;
}
注意 運(yùn)算的第一個(gè)值帶引號(hào),結(jié)果也帶引號(hào);第一個(gè)值沒有引號(hào),結(jié)果也不帶引號(hào):



