Sass 簡介
Sass 是成熟、穩定、強大的 CSS 擴展語言。完全兼容各個版本的 CSS 語法。
sass 有兩種語法,一種是以 .sass
爲擴展名的語法,寫法爲縮排語法,即不使用花括號,而是通過縮進的方式來表達選擇符的嵌套層級;而且也不使用分號,而是用換行符來分隔屬性。
另一種就是常用的以 .scss
爲擴展名的語法,寫法同 css 一樣,使用花括號和分號來表達層級和分隔屬性。
兩種語法可以相互轉換,也可同時使用。
Sass 命令行編譯
編譯
//單文件轉換命令
sass input.scss output.css
//單文件監聽命令
sass --watch input.scss:output.css
//如果你有很多的sass文件的目錄,你也可以告訴sass監聽整個目錄:
sass --watch app/sass:public/stylesheets
配置選項
通過 --style
配置編譯排版的選項。
1. nested,也是默認的
/*命令行內容*/
sass style.scss:style.css --style nested
/* 編譯過後樣式 */
.box {
width: 300px;
height: 400px; }
.box-title {
height: 30px;
line-height: 30px; }
2. expanded
/*命令行內容*/
sass style.scss:style.css --style expanded
/* 編譯過後樣式 */
.box {
width: 300px;
height: 400px;
}
.box-title {
height: 30px;
line-height: 30px;
}
3. compact
/*命令行內容*/
sass style.scss:style.css --style compact
/* 編譯過後樣式 */
.box { width: 300px; height: 400px; }
.box-title { height: 30px; line-height: 30px; }
4. compressed
/*命令行內容*/
sass style.scss:style.css --style compressed
/* 編譯過後樣式 */
.box{width:300px;height:400px}.box-title{height:30px;line-height:30px}
Sass 之基礎語法
變量
sass 最重要的一個特性就是變量。可以把項目中需要反覆使用的 css 屬性值定義成變量,然後通過變量名來引用它們,而無需重複書寫這一屬性值。比如項目中用到的色值,這樣在項目需要改版的時候可以統一改變顏色風格。
聲明與引用
- sass 使用
$
符號來標識變量。 - 在聲明變量時,變量值也可以引用其他變量。
- 也可定義在 css 規則塊內,那麼此時該變量只能在此規則塊內使用,也就是局部變量。
$primary-color: #800080;
$border: 1px solid $primary-color;
nav {
$width: 600px;
width: $width;
color: $primary-color;
}
.cancel {
background-color: #fff;
border: $border;
color: $primary-color;
}
在引用時,凡是 css 屬性值可存在的地方,變量就可以使用。編譯 css 時,變量會被它們的值所替代。
變量名
sass 的變量名可以與 css 中的屬性名和選擇器名稱相同,包括中劃線 -
和下劃線 _
。這兩種用法相互兼容。用中劃線聲明的變量可以使用下劃線的方式引用,反之亦然。
$link-color: blue;
a {
color: $link_color;
}
//編譯後
a {
color: blue;
}
嵌套
CSS 規則嵌套
.content article h1 { color: #333 }
.content article p { margin-bottom: 1.4em }
.content aside { background-color: #EEE }
這種情況下,sass 可以使用嵌套語法,然後在編譯成 css 時自動把這些嵌套規則處理好,避免重複書寫。
.content {
article {
h1 { color: #333 }
p { margin-bottom: 1.4em }
}
aside { background-color: #EEE }
}
編譯完成後的 css 寫法與上面原始 css 完全一樣。
父選擇器標識符 &
一般情況下,sass 在解開一個嵌套規則時會把父選擇器(.content
)通過一個空格連接到子選擇器的前邊(article
和aside
)形成 css 的後代選擇器。
然而在遇到 :hover
這種僞類時,如果還用空格連接,就會得不到想達到的效果,此時,就需要使用父選擇器標識符 &
來代替,在編譯時,&
被父選擇器直接替換。
article a {
color: blue;
&:hover { color: red }
}
//編譯後
article a { color: blue }
article a:hover { color: red }
羣組選擇器的嵌套
.container h1, .container h2, .container h3 {
color: $primary-color;
}
//sass 嵌套寫法
.container {
h1, h2, h3 {color: $primary-color;}
}
屬性嵌套
在 sass 中,除了 CSS 選擇器,屬性也可以進行嵌套。比如設置元素的 margin
或 padding
的 top bottom left right
等值。
.div {
margin: {
top:10px;
bottom:20px;
};
padding: {
top:5px;
bottom:5px;
left:10px;
right:20px;
};
}
嵌套屬性的規則是這樣的:把屬性名從中劃線 -
的地方斷開,在根屬性後邊添加一個冒號 :
,緊跟一個 { }
塊,把子屬性部分寫在這個{ }
塊中。就像 css 選擇器嵌套一樣,sass 會把子屬性一一解開,把根屬性和子屬性部分通過中劃線 -
連接起來,最後生成的效果與的 css 樣式一樣。
nav {
border: 1px solid #ccc {
left: 0px;
right: 0px;
}
}
混合器
像 js 的函數一樣,當項目中有一大段同樣的樣式代碼需要重複寫的時候,就要考慮將重複的部分提取出來封裝,然後在使用的時候調用。
定義與調用
sass 通過 @mixin
標識符定義混合器,在 @mixin
之後定義混合器的名字。
下邊的這段 sass 代碼,定義了一個非常簡單的混合器,目的是添加跨瀏覽器的圓角邊框。
@mixin rounded-corners {
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
border-radius: 5px;
}
在樣式表中通過 @include
來使用這個混合器。@include
標識符會把混合器中的所有樣式提取出來放在 @include
被調用的地方。
.button {
line-height: 20px;
text-align: center;
background-color: $primary-color;
color: #fff;
padding: 6px 10px;
@include rounded-corners;
}
混合器傳參
混合器並不一定總得生成相同的樣式。可以通過在 @include
調用混合器時給混合器傳參,來定製混合器生成的精確樣式。參數也是以 $
符標識。
@mixin ellipsis-line($line){
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: $line;
}
.description {
width: 600px;
height: 100px;
p {
@include ellipsis-line(3);
}
}
多個參數
當你 @include
混合器時,參數過多有時候可能會很難區分每個參數是什麼意思,參數之間是一個什麼樣的順序。爲了解決這個問題,sass 允許通過語法 $name: value
的形式指定每個參數的值。這種形式的傳參,參數順序就不重要了,只需要保證沒有漏掉參數即可:
@mixin link-colors($normal, $hover, $visited) {
color: $normal;
&:hover { color: $hover; }
&:visited { color: $visited; }
}
a {
@include link-colors(
$normal: blue,
$visited: green,
$hover: red
);
}
默認參數
爲了在 @include
混合器時不必傳入所有的參數,我們可以給參數指定一個默認值。參數默認值使用 $name: default-value
的聲明形式,默認值可以是任何有效的 css 屬性值,甚至是其他參數的引用。
@mixin link-colors(
$normal,
$hover: $normal,
$visited: $normal
)
{
color: $normal;
&:hover { color: $hover; }
&:visited { color: $visited; }
}
混合器和 class 選擇器的合理使用
混合器的方便實用導致一不小心可能就會被過度使用。大量的重用可能會導致生成的樣式表過大,導致加載緩慢。所以要明確混合器的使用場景,避免濫用。
混合器在某些方面跟 css 的 class 選擇器很像。都是給一大段樣式命名,然後可重複使用。所以在選擇使用哪個的時候可能會產生疑惑。
其最重要的區別就是 class 選擇器是在 html 文件中應用的,而混合器是在樣式表中應用的。這就意味着 class 名具有語義化含義,而不僅僅是一種展示性的描述,它用來描述 html 元素的含義而不是 html 元素的外觀。
而另一方面,混合器是展示性的描述,用來描述一條 css 規則應用之後會產生怎樣的效果。比如上例中的 .button
class 名和 rounded-corners
混合器的區別。
註釋
在模塊化開發中,多人合作,所以一些公用的文件或代碼(變量文件、@mixin文件等)就要寫明確的註釋,方便合作。而這些註釋僅開發人員可見即可,不需要瀏覽網頁源碼的人都可見。
因此 sass 另外提供了一種不同於 css 標準註釋格式 /* ... */
的註釋語法,即靜默註釋,其內容不會出現在生成的 css 文件中。
靜默註釋以 //
開頭,註釋內容直到行末。
// 這種註釋內容不會出現在生成的css文件中
/* 這種註釋內容會出現在生成的css文件中 */
@mixin link-color {}
導入
模塊化開發導入文件是必不可少的。sass 有一個 @import
規則,在編譯生成css 文件時就會把相關文件導入進來。這意味着所有相關的樣式被歸納到了同一個css 文件中,而無需發起額外的下載請求。因此,所有在被導入文件中定義的變量和混合器均可在導入文件中使用。
/* variable.scss */
$primary-color: #800080;
/* index.scss */
@import "variable";
p{
color: $primary-color;
}
以下是不同文件導入的一些用法:
1. 省略 .scss 或 .sass 後綴
使用 sass 的 @import
規則並不需要指明被導入文件的全名,可以省略後綴。這樣,在不修改樣式表的前提下,完全可以隨意修改被導入的 sass 樣式文件語法,在 sass 和 scss 語法之間隨意切換。
2. sass 局部文件,文件名以下劃線開頭。
那些專門爲 @import
命令而編寫的 sass 文件,並不需要編譯生成對應的獨立 css 文件,這樣的 sass 文件稱爲局部文件。局部文件的文件名以下劃線開頭。這樣,sass 就不會在編譯時單獨編譯這個文件輸出 css,而只把這個文件用作導入。以及當你 @import
一個局部文件時,還可以省略文件名開頭的下劃線。
/* _mixin.scss */
@mixin xxx(){};
/* index.scss */
@import "mixin";
p{
@include();
}
3. 默認變量值,!default。
跟 js 一樣,在 sass 中反覆聲明一個變量,只有最後一處聲明有效且它會覆蓋前邊的值。這種情況下如果你寫了一個可被他人通過 @import
導入的 sass 庫文件,並且希望導入者可以定製修改 sass 庫文件中的某些值,這時就需要 !default
聲明變量的默認值。
作用就是:如果這個變量被另外聲明賦值了,那就用它聲明的值,否則就用這個默認值。
/* _variable.scss */
$link-color: pink !default;
/* index.scss */
$link-color: yellow;
@import "variable";
a {
color:$link-color;
}
4. 嵌套導入
sass 允許 @import
命令寫在 css 規則內。這種導入方式下,生成對應的 css 文件時,局部文件會被直接插入到 css 規則內導入它的地方。
/* _blue-theme.scss */
aside {
background: blue;
color: #fff;
}
/* index.scss */
.blue-theme {@import "blue-theme";}
/* 相當於 */
.blue-theme {
aside {
background: blue;
color: #fff;
}
}
/* 編譯後 */
.blue-theme aside {
background: blue;
color: white;
}
被導入的局部文件中定義的所有變量和混合器,也會在這個規則範圍內生效。這些變量和混合器不會全局有效,這樣我們就可以通過嵌套導入只對站點中某一特定區域運用某種顏色主題或其他通過變量配置的樣式。
5. 原生 css 導入:以 .css
爲後綴或者 url()
導入
@import "my.css";
@import url("my.css");
css 本身就有特別不常用的 @import
規則,它允許在一個 css 文件中導入其他 css 文件。然而,運行原理是隻有瀏覽器解析到 @import
時,瀏覽器纔會去下載 @import
的 css 文件,這導致頁面會多一個請求,文件比較大的話可能加載就會變慢。
不同於 css 的是,sass 的 @import
規則,在導入 sass 文件並編譯成 css 時就把相關文件導入了進來。這意味着所有相關的樣式被歸納到了同一個 css 文件中,而無需發起額外的下載請求。
而以 .css
爲後綴或者 url()
這兩種方法導入原生 css 的時候,會在編譯完後生成原生 css 的 @import
語法,從而導致多了一些網絡請求。
/* my.css */
body {
background-color: bisque;
}
/* index.scss */
@import "my.css";
/* 編譯後 index.css */
@import url(../my.css);
因此,由於 sass 的語法完全兼容 css,所以完全可以把原始的 css 文件改名爲 .scss
後綴,然後直接導入就可以減少多餘的網絡請求了。
/* my.scss */
body {
background-color: bisque;
}
/* index.scss */
@import "my";
/* 編譯後 index.css */
body {
background-color: bisque;
}