Sass是成熟、穩(wěn)定、強大的CSS預處理器,而SCSS是Sass3版本當中引入的新語法特性,完全兼容CSS3的同時繼承了Sass強大的動態(tài)功能。
特性概覽
CSS書寫代碼規(guī)模較大的Web應(yīng)用時,容易造成選擇器、層疊的復雜度過高,因此推薦通過SASS預處理器進行CSS的開發(fā),SASS提供的變量、嵌套、混合、繼承等特性,讓CSS的書寫更加有趣與程式化。
變量
變量用來存儲需要在CSS中復用的信息,例如顏色和字體。SASS通過$符號去聲明一個變量。
$font-stack: Helvetica, sans-serif;
$primary-color: #333;
body {
font: 100% $font-stack;
color: $primary-color;
}
上面例子中變量$font-stack和$primary-color的值將會替換所有引用他們的位置。
body {
font: 100% Helvetica, sans-serif;
color: #333; }
嵌套
SASS允許開發(fā)人員以嵌套的方式使用CSS,但是過度的使用嵌套會讓產(chǎn)生的CSS難以維護,因此是一種不好的實踐,下面的例子表達了一個典型的網(wǎng)站導航樣式:
nav {
ul {
margin: 0;
padding: 0;
list-style: none;
}
li { display: inline-block; }
a {
display: block;
padding: 6px 12px;
text-decoration: none;
}
}
大家注意上面代碼中的ul、li、a選擇器都被嵌套在nav選擇器當中使用,這是一種書寫更高可讀性CSS的良好方式,編譯后產(chǎn)生的CSS代碼如下:
nav ul {
margin: 0;
padding: 0;
list-style: none; }
nav li {
display: inline-block; }
nav a {
display: block;
padding: 6px 12px;
text-decoration: none; }
引入
SASS能夠?qū)⒋a分割為多個片段,并以underscore風格的下劃線作為其命名前綴(_partial.scss),SASS會通過這些下劃線來辨別哪些文件是SASS片段,并且不讓片段內(nèi)容直接生成為CSS文件,從而只是在使用@import指令的位置被導入。CSS原生的@import會通過額外的HTTP請求獲取引入的樣式片段,而SASS的@import則會直接將這些引入的片段合并至當前CSS文件,并且不會產(chǎn)生新的HTTP請求。下面例子中的代碼,將會在base.scss文件當中引入_reset.scss片斷。
// _reset.scss
html, body, ul, ol {
margin: 0;
padding: 0;
}
// base.scss
@import 'reset';
body {
font: 100% Helvetica, sans-serif;
background-color: #efefef;
}
SASS中引入片斷時,可以缺省使用文件擴展名,因此上面代碼中直接通過@import 'reset'引入,編譯后生成的代碼如下:
html, body, ul, ol {
margin: 0;
padding: 0; }
body {
font: 100% Helvetica, sans-serif;
background-color: #efefef; }
混合
混合(Mixin)用來分組那些需要在頁面中復用的CSS聲明,開發(fā)人員可以通過向Mixin傳遞變量參數(shù)來讓代碼更加靈活,該特性在添加瀏覽器兼容性前綴的時候非常有用,SASS目前使用@mixin name指令來進行混合操作。
@mixin border-radius($radius) {
border-radius: $radius;
-ms-border-radius: $radius;
-moz-border-radius: $radius;
-webkit-border-radius: $radius;
}
.box {
@include border-radius(10px);
}
上面的代碼建立了一個名為border-radius的Mixin,并傳遞了一個變量$radius作為參數(shù),然后在后續(xù)代碼中通過@include border-radius(10px)使用該Mixin,最終編譯的結(jié)果如下:
.box {
border-radius: 10px;
-ms-border-radius: 10px;
-moz-border-radius: 10px;
-webkit-border-radius: 10px; }
繼承
繼承是SASS中非常重要的一個特性,可以通過@extend指令在選擇器之間復用CSS屬性,并且不會產(chǎn)生冗余的代碼,下面例子將會通過SASS提供的繼承機制建立一系列樣式:
// 這段代碼不會被輸出到最終生成的CSS文件,因為它沒有被任何代碼所繼承。
%other-styles {
display: flex;
flex-wrap: wrap;
}
// 下面代碼會正常輸出到生成的CSS文件,因為它被其接下來的代碼所繼承。
%message-common {
border: 1px solid #ccc;
padding: 10px;
color: #333;
}
.message {
@extend %message-common;
}
.success {
@extend %message-common;
border-color: green;
}
.error {
@extend %message-common;
border-color: red;
}
.warning {
@extend %message-common;
border-color: yellow;
}
上面代碼將.message中的CSS屬性應(yīng)用到了.success、.error、.warning上面,魔法將會發(fā)生在最終生成的CSS當中。這種方式能夠避免在HTML元素上書寫多個class選擇器,最終生成的CSS樣式是下面這樣的:
.message, .success, .error, .warning {
border: 1px solid #ccc;
padding: 10px;
color: #333; }
.success {
border-color: green; }
.error {
border-color: red; }
.warning {
border-color: yellow; }
操作符
SASS提供了標準的算術(shù)運算符,例如+、-、*、/、%。在接下來的例子里,我們嘗試在aside和article選擇器當中對寬度進行簡單的計算。
.container { width: 100%; }
article[role="main"] {
float: left;
width: 600px / 960px * 100%;
}
aside[role="complementary"] {
float: right;
width: 300px / 960px * 100%;
}
上面代碼以960px為基準建立了簡單的流式網(wǎng)格布局,SASS提供的算術(shù)運算符讓開發(fā)人員可以更容易的將像素值轉(zhuǎn)換為百分比,最終生成的CSS樣式如下所示:
.container {
width: 100%; }
article[role="main"] {
float: left;
width: 62.5%; }
aside[role="complementary"] {
float: right;
width: 31.25%; }
CSS擴展
引用父級選擇器"&"
Scss使用"&"關(guān)鍵字在CSS規(guī)則中引用父級選擇器,例如在嵌套使用偽類選擇器的場景下:
/*===== SCSS =====*/
a {
font-weight: bold;
text-decoration: none;
&:hover { text-decoration: underline; }
body.firefox & { font-weight: normal; }
}
/*===== CSS =====*/
a {
font-weight: bold;
text-decoration: none; }
a:hover {
text-decoration: underline; }
body.firefox a {
font-weight: normal; }
無論CSS規(guī)則嵌套的深度怎樣,關(guān)鍵字"&"都會使用父級選擇器級聯(lián)替換全部其出現(xiàn)的位置:
/*===== SCSS =====*/
#main {
color: black;
a {
font-weight: bold;
&:hover { color: red; }
}
}
/*===== CSS =====*/
#main {
color: black; }
#main a {
font-weight: bold; }
#main a:hover {
color: red; }
"&"必須出現(xiàn)在復合選擇器開頭的位置,后面再連接自定義的后綴,例如:
/*===== SCSS =====*/
#main {
color: black;
&-sidebar { border: 1px solid; }
}
/*===== CSS =====*/
#main {
color: black; }
#main-sidebar {
border: 1px solid; }
如果在父級選擇器不存在的場景使用&,Scss預處理器會報出錯誤信息。
嵌套屬性
CSS許多屬性都位于相同的命名空間(例如font-family、font-size、font-weight都位于font命名空間下),Scss當中只需要編寫命名空間一次,后續(xù)嵌套的子屬性都將會位于該命名空間之下,請看下面的代碼:
/*===== SCSS =====*/
.demo {
// 命令空間后帶有冒號:
font: {
family: fantasy;
size: 30em;
weight: bold;
}
}
/*===== CSS =====*/
.demo {
font-family: fantasy;
font-size: 30em;
font-weight: bold; }
命令空間上可以直接書寫CSS簡寫屬性,但是日常開發(fā)中建議直接書寫CSS簡寫屬性,盡量保持CSS語法的一致性。
.demo {
font: 20px/24px fantasy {
weight: bold;
}
}
.demo {
font: 20px/24px fantasy;
font-weight: bold;
}