和css同樣,樣式規則是Sass的基礎,原理也差很少:用選擇器選擇你所要改變樣式的元素,而後聲明一些屬性去決定它的樣式。css
Sass:git
.button { padding: 3px 10px; font-size: 12px; border-radius: 3px; border: 1px solid #e1e4e8; }
css:github
.button { padding: 3px 10px; font-size: 12px; border-radius: 3px; border: 1px solid #e1e4e8; }
1)嵌套(Nesting)web
固然Sass致力於讓碼生幸福,不會讓咱們一遍又一遍地去寫重複的選擇器,因此你能夠寫嵌套樣式,Sass會自動把外層選擇器和內層樣式規則結合起來。瀏覽器
Sass:sass
nav { ul { margin: 0; padding: 0; list-style: none; } li { display: inline-block; } a { display: block; padding: 6px 12px; text-decoration: none; } }
css:app
nav ul { margin: 0; padding: 0; list-style: none; } nav li { display: inline-block; } nav a { display: block; padding: 6px 12px; text-decoration: none; }
注意:嵌套規則很好用,可是同時你也沒法從視覺上去感覺你到底產生了多少css,嵌套得越深加載所需帶寬越高,瀏覽器渲染工做量也越大,因此儘可能嵌套淺一些。ide
1.選擇器列表(Selecor Lists)函數
嵌套規則在處理選擇器列表(就是用逗號分隔的選擇器)上仍是比較智能的,每一個複合選擇器(逗號之間的)分別嵌套,再被結合爲一個選擇器列表。this
Sass:
.alert, .warning { ul, p { margin-right: 0; margin-left: 0; padding-bottom: 0; } }
css:
.alert ul, .alert p, .warning ul, .warning p { margin-right: 0; margin-left: 0; padding-bottom: 0; }
2.選擇器鏈接符(Selector Combinators)
你也能夠嵌套使用了鏈接符的選擇器,鏈接符能夠放在外部選擇器的尾部,內部選擇器的開頭,或者是自身要鏈接的選擇器之間。
Sass:
ul > { li { list-style-type: none; } } h2 { + p { border-top: 1px solid gray; } } p { ~ { span { opacity: 0.8; } } }
css:
ul > li { list-style-type: none; } h2 + p { border-top: 1px solid gray; } p ~ span { opacity: 0.8; }
3.高級嵌套(Advanced Nesting)
萬一你不想讓你的嵌套僅僅按順序以派生鏈接符(就那空格)結合起來,Sass也是支持你的。詳情見下節父選擇器。
2)插值(Interpolation)
你可使用插值來從表達式(好比變量、函數調用)中注入動態值到你的選擇器中,這在你書寫混合變量的時候格外有用,由於這樣的話你就能夠根據用戶傳入的變量來決定使用什麼選擇器。
Sass:
@mixin define-emoji($name, $glyph) span.emoji-#{$name} font-family: IconFont font-variant: normal font-weight: normal content: $glyph @include define-emoji("women-holding-hands", "👭")
css:
@charset "UTF-8"; span.emoji-women-holding-hands { font-family: IconFont; font-variant: normal; font-weight: normal; content: "👭"; }
PS:Sass只有在求得插值以後纔會去解析選擇器,因此你能夠放心地在選擇器的任何地方使用插值,不用擔憂它是否是尚未解析。
你能夠在須要動態決定選擇器的時候把插值和父選擇器&、at-rules和選擇器函數結合使用來達到效果。詳情見下節父選擇器。
和css同樣,Sass裏的屬性聲明定義了和選擇器匹配的元素的樣式。可是Sass定義了額外的特性來加強易書寫性和智能性。重要的是,聲明的值能夠是Sass表達式,它會被求值而後包含在結果中。
Sass:
.circle { $size: 100px; width: $size; height: $size; border-radius: $size / 2; }
css:
.circle { width: 100px; height: 100px; border-radius: 50px; }
1)插值(Interpolation)
屬性名能夠包括插值,這樣的話就能夠按需決定使用哪一個屬性名了。甚至整個屬性名均可以由插值決定。
Sass:
@mixin prefix($property, $value, $prefixes) { @each $prefix in $prefixes { -#{$prefix}-#{$property}: $value; } #{$property}: $value; } .gray { @include prefix(filter, grayscale(50%), moz webkit); }
css:
.gray { -moz-filter: grayscale(50%); -webkit-filter: grayscale(50%); filter: grayscale(50%); }
2)嵌套(Nesting)
不少css屬性以相同的前綴開頭,這些前綴扮演着相似於命名空間的做用。舉個例子,font-family、font-size、font-weight就都以font-開頭。Sass經過容許屬性聲明嵌套來使寫法更加簡易。外層屬性會加到內層屬性上,經過連字符來鏈接。
Sass:
.enlarge { font-size: 14px; transition: { property: font-size; duration: 4s; delay: 2s; } &:hover { font-size: 36px; } }
css:
.enlarge { font-size: 14px; transition-property: font-size; transition-duration: 4s; transition-delay: 2s; } .enlarge:hover { font-size: 36px; }
PS:有些css屬性使用命名空間名做爲屬性名的簡略寫法,這種狀況你能夠同時使用簡略寫法和複雜的嵌套寫法。
Sass:
.info-page { margin: auto { bottom: 10px; top: 2px; } }
css:
.info-page { margin: auto; margin-bottom: 10px; margin-top: 2px; }
3)隱式聲明(Hidden Declarations)
有時候你想要一個屬性聲明只在特定時候出現,若是一個屬性的值是null或者空的未加引號的字符串,Sass就不會把它編譯到css中。
$rounded-corners: false; .button { border: 1px solid black; border-radius: if($rounded-corners, 5px, null); }
css:
.button { border: 1px solid black; }
4)自定義屬性(Custom Properties)
css自定義屬性,也被稱爲css變量,它們的聲明語法比較特殊,容許變量名包含幾乎任何文本,並且這些變量JavaScript也能夠訪問,因此任何變量對於書寫者來講均可能有意義,包括被正常轉爲SassScript的變量。所以Sass解析自定義屬性聲明的時候跟正常屬性聲明不同。全部相似於SassScript的字符會原樣輸出爲css。惟一注入動態變量到自定義屬性的方法是插值。
Sass:
$primary: #81899b; $accent: #302e24; $warn: #dfa612; :root { --primary: #{$primary}; --accent: #{$accent}; --warn: #{$warn}; // Even though this looks like a Sass variable, it's valid CSS so it's not // evaluated. --consumed-by-js: $primary; }
css:
:root { --primary: #81899b; --accent: #302e24; --warn: #dfa612; --consumed-by-js: $primary; }
注意:不幸的是插值會移除字符串的引號,因此未來自Sass變量的被引號包裹的字符串注入自定義屬性就比較困難,可是你可使用inspect()方法來保留引號。
Sass:
$font-family-sans-serif: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto; $font-family-monospace: SFMono-Regular, Menlo, Monaco, Consolas; :root { --font-family-sans-serif: #{inspect($font-family-sans-serif)}; --font-family-monospace: #{inspect($font-family-monospace)}; }
css:
:root { --font-family-sans-serif: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto; --font-family-monospace: SFMono-Regular, Menlo, Monaco, Consolas; }
父選擇器&是Sass首創的一個選擇器,用於在嵌套選擇器中指向其外層選擇器,利用父選擇器能夠實現外層選擇器的多重複雜重用,好比增長一個僞類或者其餘選擇器。
和正常的嵌套機制不一樣,當父選擇器在一個選擇器內部使用時它指代的就是這個選擇器。
Sass:
.alert { // The parent selector can be used to add pseudo-classes to the outer // selector. &:hover { font-weight: bold; } // It can also be used to style the outer selector in a certain context, such // as a body set to use a right-to-left language. [dir=rtl] & { margin-left: 0; margin-right: 10px; } // You can even use it as an argument to pseudo-class selectors. :not(&) { opacity: 0.8; } }
css:
.alert:hover { font-weight: bold; } [dir=rtl] .alert { margin-left: 0; margin-right: 10px; } :not(.alert) { opacity: 0.8; }
注意:因爲父選擇器能夠表明類選擇器好比h1,它只能出如今類選擇器可以出現的地方即複合選擇器開頭,例如span&就是不合法的寫法。咱們也在嘗試放鬆這些限制,你想的話能夠加入咱們。
1)添加後綴(Adding Suffix)
你也可使用父選擇器來爲外層選擇器添加後綴,這在使用某些例如BEM這種使用高度結構化類名的命名原則時會格外有用,只要外層選擇器以含有字母和數字的名稱(好比class,id,元素選擇器)結尾,你就可使用父選擇器添加額外文本。
Sass:
.accordion { max-width: 600px; margin: 4rem auto; width: 90%; font-family: "Raleway", sans-serif; background: #f4f4f4; &__copy { display: none; padding: 1rem 1.5rem 2rem 1.5rem; color: gray; line-height: 1.6; font-size: 14px; font-weight: 500; &--open { display: block; } } }
css:
.accordion { max-width: 600px; margin: 4rem auto; width: 90%; font-family: "Raleway", sans-serif; background: #f4f4f4; } .accordion__copy { display: none; padding: 1rem 1.5rem 2rem 1.5rem; color: gray; line-height: 1.6; font-size: 14px; font-weight: 500; } .accordion__copy--open { display: block; }
2)SassScript用法(In SassScript)
父選擇器能夠在SassScript中使用,屬於特殊表達式,返回當前父選擇器,和選擇器函數使用的格式同樣,包含以空格分隔的列表即複雜選擇器(the complex selectors )的以逗號分隔的選擇器列表(the selector list),複雜選擇器又可能包含不帶引號的字符串即複合選擇器(the compound selectors)。
Sass:
SCSS SYNTAX .main aside:hover, .sidebar p { parent-selector: &; // => ((unquote(".main") unquote("aside:hover")), // (unquote(".sidebar") unquote("p"))) }
css:
.main aside:hover, .sidebar p { parent-selector: .main aside:hover, .sidebar p; }
若是父選擇器在樣式規則外層使用,它會返回null,而null屬於falsey,所以你能夠藉此來決定在一個樣式規則中要不要引用一個混合類型。
Sass:
@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(#c6538c); }
css:
.app-background { background-color: #036; color: rgba(255, 255, 255, 0.75); } .sidebar.app-background { background-color: #c6538c; color: rgba(255, 255, 255, 0.75); }
高級嵌套(Advanced Nesting)
你能夠把父選擇器做爲正常表達式使用,也就是說你能夠把它傳入函數或者插值,即便是在別的選擇器裏。結合選擇器函數和@at-root規則使用能夠達到很是強大的嵌套效果。
舉個例子,假設你要寫一個選擇器來匹配外層選擇器和一個元素選擇器,你能夠像這樣使用selector-unify()函數來結合父選擇器和另外一個自定義選擇器:
Sass:
@mixin unify-parent($child) { @at-root #{selector-unify(&, $child)} { @content; } } .wrapper .field { @include unify-parent("input") { /* ... */ } @include unify-parent("select") { /* ... */ } }
css:
.wrapper input.field { /* ... */ } .wrapper select.field { /* ... */ }
注意:Sass在處理嵌套的時候,它也不知道這些選擇器是由什麼樣的插值產生的,因此它會自動把外層選擇器加到內層選擇器前面,即便你使用了父選擇器做爲SassScript表達式。因此你要使用@at-root規則來明確告訴Sass不要去包含外層選擇器。
Sass還有一種特殊的選擇器‘佔位符’。它的長相和行爲都很像一個類選擇器,不一樣的是它以%開頭而且不輸出到css中。事實上,任何含有了佔位符選擇器的複雜選擇器(被逗號隔離的那些)及其對應樣式規則都不會被輸出到css中。
Sass:
.alert:hover, %strong-alert { font-weight: bold; } %strong-alert:hover { color: red; }
css:
.alert:hover { font-weight: bold; }
一個選擇器它都被所有忽略了那要它幹嗎?誒,它還能夠被擴展。不像類選擇器,若是不進行擴展,而且不要求庫的用戶爲其HTML使用特定的類名,則佔位符不會出現使得css一團亂。
Sass:
%toolbelt { box-sizing: border-box; border-top: 1px rgba(#000, .12) solid; padding: 16px 0; width: 100%; &:hover { border: 2px rgba(#000, .5) solid; } } .action-buttons { @extend %toolbelt; color: #4285f4; } .reset-buttons { @extend %toolbelt; color: #cddc39; }
css:
.action-buttons, .reset-buttons { box-sizing: border-box; border-top: 1px rgba(0, 0, 0, 0.12) solid; padding: 16px 0; width: 100%; } .action-buttons:hover, .reset-buttons:hover { border: 2px rgba(0, 0, 0, 0.5) solid; } .action-buttons { color: #4285f4; } .reset-buttons { color: #cddc39; }
在編寫一個Sass庫時有些樣式規則只須要某些狀況下起做用,這時候佔位符就顯得格外有用。但根據經驗,若是你只是爲本身的應用編寫樣式表的話,若是有可用的類選擇器,擴展類選擇器一般更好。