嵌套巢狀(Nesting)
Sass 嵌套可以解決 CSS 階層結構重複撰寫的問題。
#content article h1 { color: #333; } #content article p { margin-bottom: 1.4em; } #content aside { background-color: #eee; }
|
Sass 可以讓撰寫樣式更輕鬆。可以一次編寫一個樣式階層規則,而不必一次又一次地重複使用相同的選擇器,這種方式常使用於後代選擇器方式。Sass 會將自動將它們組合在一起,避免重複撰寫,讓樣式可讀性提高。這就好像俄羅斯娃娃一樣,每一層就像打開一個俄羅斯娃娃,可以很清楚每一層的關係。雖然,Nesting 嵌套功能非常方便,但有過度階層化的陷阱,會造成選擇器的層級過深,不超過 3 層即可。
#content { article { h1 { color: #333; } p { margin-bottom: 1.4em; } } aside { background-color: #eee; } }
|
嵌套屬性(Neseted Properties)
屬性嵌套被使用在屬性有相同的字元,例如:font-family、font-size、font-weight 都是以 font 作為屬性命名空間,為了避免重複輸入而使用屬性嵌套。
.font-setting { font: { family: '微軟正黑體'; size: 2rem; weight: bold; } }
nav { border: { style: solid; width: 1px; color: #ccc; } }
.font-setting { font-family: '微軟正黑體'; font-size: 2rem; font-weight: bold; }
nav { border-style: solid; border-width: 1px; border-color: #ccc; }
|
使用 & 與父選擇器連結
在嵌套 CSS 規則時,若遇到偽類,使用後代選擇器的方式就不適用,此時需要與父層連結,例如元素設定 :hover 樣式時,以下例子編譯後 & 會直接替換成父選擇器來用。
div a { color: blue; :hover { color: red; } }
div a { color: blue; &:hover { color: red; } }
|
如果沒有父選擇器,& 的值將是空。這意味著你可以在一個 mixin 中使用它來檢測父選擇是否存在。
@mixin does-parent-exist { @if & { &:hover { color: red; } } @else { a { color: red; } } }
|
雖然 body.ie 在巢狀裡面,但因為使用 &,編譯出來會獨立出自己的樣式,但是寫在別人巢狀裡面會有較難以閱讀的問題。
#content aside { color: red; body.ie & { color: green; } }
#content aside { color: red; } body.ie #content aside { color: green; }
|
.alert { &:hover { font-weight { font-weight: bold; } } [dir='rtl'] & { margin-left: 0; margin-right: 10px; }
body.box & { color: Red; }
:not(&) { opacity: 0.8; } }
.alert:hover font-weight { font-weight: bold; }
[dir='rtl'] .alert { margin-left: 0; margin-right: 10px; }
body.box .alert { color: Red; }
:not(.alert) { opacity: 0.8; }
|
可以使用 & 增加後綴詞:
- & 作為選擇器的第一個字符,其後可以跟隨後綴詞產生複合選擇器。
- & 必須出現在的選擇器的開頭位置(愚人碼頭注:也就是作為選擇器的第一個字符),但可以跟隨後綴,將被添加到父選擇的後面。
.btn { display: inline-block; color: #212529; text-align: center; vertical-align: middle; background-color: transparent; border: 1px solid transparent; padding: 0.375rem 0.75rem; line-height: 1.5; border-radius: 0.25rem;
&-primary { color: #fff; background-color: #007bff; border-color: #007bff; &:hover { color: #fff; background-color: #0069d9; border-color: #0062cc; } }
&-lg { padding: 0.5rem 1rem; font-size: 1.25rem; line-height: 1.5; border-radius: 0.3rem; } }
.btn { display: inline-block; color: #212529; text-align: center; vertical-align: middle; background-color: transparent; border: 1px solid transparent; padding: 0.375rem 0.75rem; line-height: 1.5; border-radius: 0.25rem; }
.btn-primary { color: #fff; background-color: #007bff; border-color: #007bff; }
.btn-primary:hover { color: #fff; background-color: #0069d9; border-color: #0062cc; }
.btn-lg { padding: 0.5rem 1rem; font-size: 1.25rem; line-height: 1.5; border-radius: 0.3rem; }
|
& 與判斷式 if
@mixin app-background($color) { #{if(&,'&.app-background','.app-background')} { background-color: $color; color: rgba(#fff, 0.75); } }
@include app-background(#036);
.sidebar { @include app-background(#c6539c); }
.app-background { background-color: #036; color: rgba(255, 255, 255, 0.75); }
.sidebar.app-background { background-color: #c6539c; color: rgba(255, 255, 255, 0.75); }
|
進階 & 使用
@mixin unify-parent($child) { @at-root #{selector.unify(&, $child)} { @content; } }
.wrapper .field { @include unify-parent('input') { } @include unify-parent('select') { } }
.wrapper input.field { }
.wrapper select.field { }
|
群組選擇器(逗號分隔的選擇器)
.container { h1, h2, h3 { margin-bottom: 0.8em; } }
.container h1, .container h2, .container h3 { margin-bottom: 0.8em; }
|
與各選擇器的結合
ul { > li { list-style: none; } }
h2 { + p { border-top: 1px solid gray; } }
p { ~ span { opacity: 0.8; } }
ul > li { list-style-type: none; }
h2 + p { border-top: 1px solid gray; }
p ~ span { opacity: 0.8; }
|
@at-root
@at-root 可以寫在階層內,它會跳脫父層獨立出來。
.parent { color: black; @at-root { .child1 { color: black; } .child2 { color: black; } } }
.parent { color: black; }
.child1 { color: black; }
.child2 { color: black; }
|
另一個例子
.tooltip { font-size: 20px; @at-root body.active .tooltip-backdrop { position: fixed; } }
.tooltip { font-size: 20px; }
body.active .tooltip-backdrop { position: fixed; }
|