sass
讓人們受益的一個重要特性就是它爲css
引入了變量。你能夠把反覆使用的css
屬性值 定義成變量,而後經過變量名來引用它們,而無需重複書寫這一屬性值。或者,對於僅使用過一 次的屬性值,你能夠賦予其一個易懂的變量名,讓人一眼就知道這個屬性值的用途。css
sass
使用$
符號來標識變量(老版本的sass
使用!
來標識變量。改爲$是多半由於!highlight-color
看起來太醜了。),好比$highlight-color
和$sidebar-width
。爲何選擇$
符號呢?由於它好認、更具美感,且在CSS中並沒有他用,不會致使與現存或將來的css
語法衝突。html
sass
變量的聲明和css
屬性的聲明很像:web
$highlight-color: #F90;
這意味着變量$highlight-color
如今的值是#F90
。任何能夠用做css
屬性值的賦值都 能夠用做sass
的變量值,甚至是以空格分割的多個屬性值,如$basic-border: 1px solid black;
,或以逗號分割的多個屬性值,如$plain-font: "Myriad Pro"、Myriad、"Helvetica Neue"、Helvetica、"Liberation Sans"、Arial和sans-serif; sans-serif;
。這時變 量尚未生效,除非你引用這個變量——咱們很快就會了解如何引用。瀏覽器
與CSS
屬性不一樣,變量能夠在css
規則塊定義以外存在。當變量定義在css
規則塊內,那麼該變量只能在此規則塊內使用。若是它們出如今任何形式的{...}
塊中(如@media
或者@font-face
塊),狀況也是如此:sass
$nav-color: #F90; nav { $width: 100px; width: $width; color: $nav-color; } //編譯後 nav { width: 100px; color: #F90; }
在這段代碼中,$nav-color
這個變量定義在了規則塊外邊,因此在這個樣式表中均可以像 nav
規則塊那樣引用它。$width
這個變量定義在了nav
的{ }
規則塊內,因此它只能在nav
規則塊 內使用。這意味着是你能夠在樣式表的其餘地方定義和使用$width
變量,不會對這裏形成影響。ide
只聲明變量其實沒啥用處,咱們最終的目的仍是使用它們。上例已介紹瞭如何使用 $nav-color
和$width
這兩個變量,接下來咱們將進一步探討變量的使用方法。函數
凡是css
屬性的標準值(好比說1px或者bold)可存在的地方,變量就可使用。css
生成時,變量會被它們的值所替代。以後,若是你須要一個不一樣的值,只須要改變這個變量的值,則全部引用此變量的地方生成的值都會隨之改變。工具
$highlight-color: #F90; .selected { border: 1px solid $highlight-color; } //編譯後 .selected { border: 1px solid #F90; }
看上邊示例中的$highlight-color
變量,它被直接賦值給border
屬性,當這段代碼被編譯輸出css
時,$highlight-color
會被#F90
這一顏色值所替代。產生的效果就是給selected
這個類一條1像素寬、實心且顏色值爲#F90
的邊框。性能
在聲明變量時,變量值也能夠引用其餘變量。當你經過粒度區分,爲不一樣的值取不一樣名字時,這至關有用。下例在獨立的顏色值粒度上定義了一個變量,且在另外一個更復雜的邊框值粒度上也定義了一個變量:學習
$highlight-color: #F90; $highlight-border: 1px solid $highlight-color; .selected { border: $highlight-border; } //編譯後 .selected { border: 1px solid #F90; }
這裏,$highlight-border
變量的聲明中使用了$highlight-color
這個變量。產生的效 果就跟你直接爲border
屬性設置了一個1px
$highlight-color solid
的值是同樣的。 最後,咱們來了解一下變量命名的實用技巧,以結束關於變量的介紹。
sass
的變量名能夠與css
中的屬性名和選擇器名稱相同,包括中劃線和下劃線。這徹底取決於我的的喜愛,有些人喜歡使用中劃線來分隔變量中的多個詞(如$highlight-color
),而有些人喜歡使用下劃線(如$highlight_color
)。使用中劃線的方式更爲廣泛,這也是compass
和本文都用的方式。
不過,sass
並不想強迫任何人必定使用中劃線或下劃線,因此這兩種用法相互兼容。用中劃線聲明的變量可使用下劃線的方式引用,反之亦然。這意味着即便compass
選擇用中劃線的命名方式,這並不影響你在使用compass
的樣式中用下劃線的命名方式進行引用:
$link-color: blue; a { color: $link_color; } //編譯後 a { color: blue; }
在上例中,$link-color
和$link_color
其實指向的是同一個變量。實際上,在sass
的大 多數地方,中劃線命名的內容和下劃線命名的內容是互通的,除了變量,也包括對混合器和Sass函數的命名。可是在sass
中純css
部分不互通,好比類名、ID或屬性名。
儘管變量自身提供了不少有用的地方,可是sass
基於變量提供的更爲強大的工具纔是咱們關注的焦點。只有當變量與sass
的其餘特性一塊兒使用時,才能發揮其所有的潛能。接下來,咱們將探討其中一個很是重要的特性,即規則嵌套。
css
中重複寫選擇器是很是惱人的。若是要寫一大串指向頁面中同一塊的樣式時,每每須要 一遍又一遍地寫同一個ID
:
#content article h1 { color: #333 } #content article p { margin-bottom: 1.4em } #content aside { background-color: #EEE }
像這種狀況,sass
可讓你只寫一遍,且使樣式可讀性更高。在Sass中,你能夠像俄羅斯套娃那樣在規則塊中嵌套規則塊。sass
在輸出css
時會幫你把這些嵌套規則處理好,避免你的重複書寫。
#content { article { h1 { color: #333 } p { margin-bottom: 1.4em } } aside { background-color: #EEE } }
/* 編譯後 */ #content article h1 { color: #333 } #content article p { margin-bottom: 1.4em } #content aside { background-color: #EEE }
上邊的例子,會在輸出css
時把它轉換成跟你以前看到的同樣的效果。這個過程當中,sass
用了兩步,每一步都是像打開俄羅斯套娃那樣把裏邊的嵌套規則塊一個個打開。首先,把#content
(父級)這個id
放到article
選擇器(子級)和aside
選擇器(子級)的前邊:
#content { article { h1 { color: #333 } p { margin-bottom: 1.4em } } #content aside { background-color: #EEE } }
/* 編譯後 */ #content article h1 { color: #333 } #content article p { margin-bottom: 1.4em } #content aside { background-color: #EEE }
而後,#content article
裏邊還有嵌套的規則,sass
重複一遍上邊的步驟,把新的選擇器添加到內嵌的選擇器前邊。
一個給定的規則塊,既能夠像普通的CSS那樣包含屬性,又能夠嵌套其餘規則塊。當你同時要爲一個容器元素及其子元素編寫特定樣式時,這種能力就很是有用了。
#content { background-color: #f5f5f5; aside { background-color: #eee } }
容器元素的樣式規則會被單獨抽離出來,而嵌套元素的樣式規則會像容器元素沒有包含任何屬性時那樣被抽離出來。
#content { background-color: #f5f5f5 } #content aside { background-color: #eee }
大多數狀況下這種簡單的嵌套都沒問題,可是有些場景下不行,好比你想要在嵌套的選擇器 裏邊馬上應用一個相似於:hover
的僞類。爲了解決這種以及其餘狀況,sass
提供了一個特殊結 構&
。
通常狀況下,sass
在解開一個嵌套規則時就會把父選擇器(#content
)經過一個空格鏈接到子選擇器的前邊(article
和aside
)造成(#content article
和#content aside
)。這種在CSS裏邊被稱爲後代選擇器,由於它選擇ID爲content
的元素內全部命中選擇器article
和aside
的元素。但在有些狀況下你卻不會但願sass
使用這種後代選擇器的方式生成這種鏈接。
最多見的一種狀況是當你爲連接之類的元素寫:hover
這種僞類時,你並不但願之後代選擇器的方式鏈接。好比說,下面這種狀況sass
就沒法正常工做:
article a { color: blue; :hover { color: red } }
這意味着color: red
這條規則將會被應用到選擇器article a :hover
,article
元素內連接的全部子元素在被hover
時都會變成紅色。這是不正確的!你想把這條規則應用到超連接自身,然後代選擇器的方式沒法幫你實現。
解決之道爲使用一個特殊的sass
選擇器,即父選擇器。在使用嵌套規則時,父選擇器能對於嵌套規則如何解開提供更好的控制。它就是一個簡單的&
符號,且能夠放在任何一個選擇器可出現的地方,好比h1
放在哪,它就能夠放在哪。
article a { color: blue; &:hover { color: red } }
當包含父選擇器標識符的嵌套規則被打開時,它不會像後代選擇器那樣進行拼接,而是&
被父選擇器直接替換:
article a { color: blue } article a:hover { color: red }
在爲父級選擇器添加:hover
等僞類時,這種方式很是有用。同時父選擇器標識符還有另一種用法,你能夠在父選擇器以前添加選擇器。舉例來講,當用戶在使用IE瀏覽器時,你會經過JavaScript
在<body>
標籤上添加一個ie的類名,爲這種狀況編寫特殊的樣式以下:
#content aside { color: red; body.ie & { color: green } }
/*編譯後*/ #content aside {color: red}; body.ie #content aside { color: green }
sass
在選擇器嵌套上是很是智能的,即便是帶有父選擇器的狀況。當sass
遇到羣組選擇器(由多個逗號分隔開的選擇器造成)也能完美地處理這種嵌套。
在CSS
裏邊,選擇器h1
h2
和h3
會同時命中h1元素、h2元素和h3元素。與此相似,.button
button
會命中button元素和類名爲.button的元素。這種選擇器稱爲羣組選擇器。羣組選擇器 的規則會對命中羣組中任何一個選擇器的元素生效。
.button, button { margin: 0; }
當看到上邊這段代碼時,你可能還沒意識到會有重複性的工做。但會很快發現:若是你須要在一個特定的容器元素內對這樣一個羣組選擇器進行修飾,狀況就不一樣了。css
的寫法會讓你在羣組選擇器中的每個選擇器前都重複一遍容器元素的選擇器。
.container h1, .container h2, .container h3 { margin-bottom: .8em }
很是幸運,sass
的嵌套特性在這種場景下也很是有用。當sass
解開一個羣組選擇器規則內嵌的規則時,它會把每個內嵌選擇器的規則都正確地解出來:
.container { h1, h2, h3 {margin-bottom: .8em} }
首先sass
將.container
和h1
.container
和h2
.container
和h3
分別組合,而後將三 者從新組合成一個羣組選擇器,生成你前邊看到的普通css
樣式。對於內嵌在羣組選擇器內的嵌 套規則,處理方式也同樣:
nav, aside { a {color: blue} }
首先sass
將nav
和a
aside
和a
分別組合,而後將兩者從新組合成一個羣組選擇器:
nav a, aside a {color: blue}
處理這種羣組選擇器規則嵌套上的強大能力,正是sass
在減小重複敲寫方面的貢獻之一。尤爲在當嵌套級別達到兩層甚至三層以上時,與普通的css
編寫方式相比,只寫一遍羣組選擇器大大減小了工做量。
有利必有弊,你須要特別注意羣組選擇器的規則嵌套生成的css
。雖然sass
讓你的樣式表看上去很小,但實際生成的css
卻可能很是大,這會下降網站的速度。
關於選擇器嵌套的最後一個方面,咱們看看sass
如何處理組合選擇器,好比>、+和~的使用。你將看到,這種場景下你甚至無需使用父選擇器標識符。
上邊這三個組合選擇器必須和其餘選擇器配合使用,以指定瀏覽器僅選擇某種特定上下文中的元素。
article section { margin: 5px } article > section { border: 1px solid #ccc }
你能夠用子組合選擇器>選擇一個元素的直接子元素。上例中,第一個選擇器會選擇article下的全部命中section選擇器的元素。第二個選擇器只會選擇article下緊跟着的子元素中命中section選擇器的元素。
在下例中,你能夠用同層相鄰組合選擇器+
選擇header
元素後緊跟的p
元素:
header + p { font-size: 1.1em }
你也能夠用同層全體組合選擇器~
,選擇全部跟在article
後的同層article
元素,無論它們之間隔了多少其餘元素:
article ~ article { border-top: 1px dashed #ccc }
這些組合選擇器能夠絕不費力地應用到sass
的規則嵌套中。能夠把它們放在外層選擇器後邊,或裏層選擇器前邊:
article { ~ article { border-top: 1px dashed #ccc } > section { background: #eee } dl > { dt { color: #333 } dd { color: #555 } } nav + & { margin-top: 0 } }
sass
會如你所願地將這些嵌套規則一一解開組合在一塊兒:
article ~ article { border-top: 1px dashed #ccc } article > footer { background: #eee } article dl > dt { color: #333 } article dl > dd { color: #555 } nav + article { margin-top: 0 }
在sass
中,不只僅css
規則能夠嵌套,對屬性進行嵌套也能夠減小不少重複性的工做。
在sass
中,除了CSS選擇器,屬性也能夠進行嵌套。儘管編寫屬性涉及的重複不像編寫選擇器那麼糟糕,可是要反覆寫border-style
border-width
border-color
以及border-*
等也是很是煩人的。在sass
中,你只需敲寫一遍border
:
nav { border: { style: solid; width: 1px; color: #ccc; } }
嵌套屬性的規則是這樣的:把屬性名從中劃線-的地方斷開,在根屬性後邊添加一個冒號:,緊跟一個{ }
塊,把子屬性部分寫在這個{ }
塊中。就像css
選擇器嵌套同樣,sass
會把你的子屬性一一解開,把根屬性和子屬性部分經過中劃線-鏈接起來,最後生成的效果與你手動一遍遍寫的css
樣式同樣:
nav { border-style: solid; border-width: 1px; border-color: #ccc; }
對於屬性的縮寫形式,你甚至能夠像下邊這樣來嵌套,指明例外規則:
nav { border: 1px solid #ccc { left: 0px; right: 0px; } }
這比下邊這種同等樣式的寫法要好:
nav { border: 1px solid #ccc; border-left: 0px; border-right: 0px; }
屬性和選擇器嵌套是很是偉大的特性,由於它們不只大大減小了你的編寫量,並且經過視覺上的縮進使你編寫的樣式結構更加清晰,更易於閱讀和開發。
即使如此,隨着你的樣式表變得愈來愈大,這種寫法也很難保持結構清晰。有時,處理這種大量樣式的惟一方法就是把它們分拆到多個文件中。sass
經過對css
原有@import
規則的改進直接支持了這一特性。
css
有一個特別不經常使用的特性,即@import
規則,它容許在一個css
文件中導入其餘css
文件。然而,後果是隻有執行到@import
時,瀏覽器纔會去下載其餘css
文件,這致使頁面加載起來特別慢。
sass
也有一個@import
規則,但不一樣的是,sass
的@import
規則在生成css
文件時就把相關文件導入進來。這意味着全部相關的樣式被概括到了同一個css
文件中,而無需發起額外的下載請求。另外,全部在被導入文件中定義的變量和混合器(參見2.5節)都可在導入文件中使用。
使用sass
的@import
規則並不須要指明被導入文件的全名。你能夠省略.sass
或.scss
文件後綴(見下圖)。這樣,在不修改樣式表的前提下,你徹底能夠隨意修改你或別人寫的被導入的sass
樣式文件語法,在sass
和scss
語法之間隨意切換。舉例來講,@import
"sidebar";這條命令將把sidebar.scss
文件中全部樣式添加到當前樣式表中。
本節將介紹如何使用sass
的@import
來處理多個sass
文件。首先,咱們將學習編寫那些被導入的sass
文件,由於在一個大型sass
項目中,這樣的文件是你最常編寫的那一類。接着,瞭解集中導入sass
文件的方法,使你的樣式可重用性更高,包括聲明可自定義的變量值,以及在某一個選擇器範圍內導入sass
文件。最後,介紹如何在sass
中使用css
原生的@import
命令。
一般,有些sass
文件用於導入,你並不但願爲每一個這樣的文件單獨地生成一個css
文件。對此,sass
用一個特殊的約定來解決。
當經過@import
把sass
樣式分散到多個文件時,你一般只想生成少數幾個css
文件。那些專門爲@import
命令而編寫的sass
文件,並不須要生成對應的獨立css
文件,這樣的sass
文件稱爲局部文件。對此,sass
有一個特殊的約定來命名這些文件。
此約定即,sass
局部文件的文件名如下劃線開頭。這樣,sass
就不會在編譯時單獨編譯這個文件輸出css
,而只把這個文件用做導入。當你@import
一個局部文件時,還能夠不寫文件的全名,即省略文件名開頭的下劃線。舉例來講,你想導入themes/_night-sky.scss
這個局部文件裏的變量,你只需在樣式表中寫@import
"themes/night-sky";
。
局部文件能夠被多個不一樣的文件引用。當一些樣式須要在多個頁面甚至多個項目中使用時,這很是有用。在這種狀況下,有時須要在你的樣式表中對導入的樣式稍做修改,sass
有一個功能恰好能夠解決這個問題,即默認變量值。
通常狀況下,你反覆聲明一個變量,只有最後一處聲明有效且它會覆蓋前邊的值。舉例說明:
$link-color: blue; $link-color: red; a { color: $link-color; }
在上邊的例子中,超連接的color
會被設置爲red
。這可能並非你想要的結果,假如你寫了一個可被他人經過@import
導入的sass
庫文件,你可能但願導入者能夠定製修改sass
庫文件中的某些值。使用sass
的!default
標籤能夠實現這個目的。它很像css
屬性中!important
標籤的對立面,不一樣的是!default
用於變量,含義是:若是這個變量被聲明賦值了,那就用它聲明的值,不然就用這個默認值。
$fancybox-width: 400px !default; .fancybox { width: $fancybox-width; }
在上例中,若是用戶在導入你的sass
局部文件以前聲明瞭一個$fancybox-width
變量,那麼你的局部文件中對$fancybox-width
賦值400px
的操做就無效。若是用戶沒有作這樣的聲明,則$fancybox-width
將默認爲400px
。
接下來咱們將學習嵌套導入,它容許只在某一個選擇器的範圍內導入sass
局部文件。
跟原生的css
不一樣,sass
容許@import
命令寫在css
規則內。這種導入方式下,生成對應的css
文件時,局部文件會被直接插入到css
規則內導入它的地方。舉例說明,有一個名爲_blue-theme.scss
的局部文件,內容以下:
aside { background: blue; color: white; }
而後把它導入到一個CSS規則內,以下所示:
.blue-theme {@import
"blue-theme"} //生成的結果跟你直接在.blue-theme選擇器內寫_blue-theme.scss文件的內容徹底同樣。 .blue-theme { aside { background: blue; color: #fff; } }@import
被導入的局部文件中定義的全部變量和混合器,也會在這個規則範圍內生效。這些變量和混合器不會全局有效,這樣咱們就能夠經過嵌套導入只對站點中某一特定區域運用某種顏色主題或其餘經過變量配置的樣式。
有時,可用css
原生的@import
機制,在瀏覽器中下載必需的css
文件。sass
也提供了幾種方法來達成這種需求。
因爲sass
兼容原生的css
,因此它也支持原生的CSS@import
。儘管一般在sass
中使用@import
時,sass
會嘗試找到對應的sass
文件並導入進來,但在下列三種狀況下會生成原生的CSS@import
,儘管這會形成瀏覽器解析css
時的額外下載:
.css
結尾;CSS
的url()值。這就是說,你不能用sass
的@import
直接導入一個原始的css
文件,由於sass
會認爲你想用css
原生的@import
。可是,由於sass
的語法徹底兼容css
,因此你能夠把原始的css
文件更名爲.scss
後綴,便可直接導入了。
文件導入是保證sass
的代碼可維護性和可讀性的重要一環。次之但亦很是重要的就是註釋了。註釋能夠幫助樣式做者記錄寫sass
的過程當中的想法。在原生的css
中,註釋對於其餘人是直接可見的,但sass
提供了一種方式可在生成的css
文件中按需抹掉相應的註釋。
css
中註釋的做用包括幫助你組織樣式、之後你看本身的代碼時明白爲何這樣寫,以及簡單的樣式說明。可是,你並不但願每一個瀏覽網站源碼的人都能看到全部註釋。
sass
另外提供了一種不一樣於css
標準註釋格式/* ... */
的註釋語法,即靜默註釋,其內容不會出如今生成的css
文件中。靜默註釋的語法跟JavaScript
Java
等類C
的語言中單行註釋的語法相同,它們以//
開頭,註釋內容直到行末。
body { color: #333; // 這種註釋內容不會出如今生成的css文件中 padding: 0; /* 這種註釋內容會出如今生成的css文件中 */ }
實際上,css
的標準註釋格式/* ... */
內的註釋內容亦可在生成的css
文件中抹去。當註釋出如今原生css
不容許的地方,如在css
屬性或選擇器中,sass
將不知如何將其生成到對應css
文件中的相應位置,因而這些註釋被抹掉。
body { color /* 這塊註釋內容不會出如今生成的css中 */: #333; padding: 1; /* 這塊註釋內容也不會出如今生成的css中 */ 0; }
你已經掌握了sass
的靜默註釋,瞭解了保持sass
條理性和可讀性的最基本的三個方法:嵌套、導入和註釋。如今,咱們要進一步學習新特性,這樣咱們不但能保持條理性還能寫出更好的樣式。首先要介紹的內容是:使用混合器抽象你的相關樣式。
若是你的整個網站中有幾處小小的樣式相似(例如一致的顏色和字體),那麼使用變量來統一處理這種狀況是很是不錯的選擇。可是當你的樣式變得愈來愈複雜,你須要大段大段的重用樣式的代碼,獨立的變量就沒辦法應付這種狀況了。你能夠經過sass
的混合器實現大段樣式的重用。
混合器使用@mixin
標識符定義。看上去很像其餘的CSS @
標識符,好比說@media
或者@font-face
。這個標識符給一大段樣式賦予一個名字,這樣你就能夠輕易地經過引用這個名字重用這段樣式。下邊的這段sass
代碼,定義了一個很是簡單的混合器,目的是添加跨瀏覽器的圓角邊框。
@mixin rounded-corners { -moz-border-radius: 5px; -webkit-border-radius: 5px; border-radius: 5px; }
而後就能夠在你的樣式表中經過@include
來使用這個混合器,放在你但願的任何地方。@include
調用會把混合器中的全部樣式提取出來放在@include
被調用的地方。若是像下邊這樣寫:
notice {
background-color: green; border: 2px solid #00aa00; @include rounded-corners; } //sass最終生成:
.notice { background-color: green; border: 2px solid #00aa00; -moz-border-radius: 5px; -webkit-border-radius: 5px; border-radius: 5px; }
在.notice
中的屬性border-radius
-moz-border-radius
和-webkit-border-radius
所有來自rounded-corners
這 個混合器。這一節將介紹使用混合器來避免重複。經過使用參數,你可使用混合器把你樣式中的通用樣式抽離出來,而後輕鬆地在其餘地方重用。實際上,混合器 太好用了,一不當心你可能會過分使用。大量的重用可能會致使生成的樣式表過大,致使加載緩慢。因此,首先咱們將討論混合器的使用場景,避免濫用。
利用混合器,能夠很容易地在樣式表的不一樣地方共享樣式。若是你發現本身在不停地重複一段樣式,那就應該把這段樣式構形成優良的混合器,尤爲是這段樣式自己就是一個邏輯單元,好比說是一組放在一塊兒有意義的屬性。
判斷一組屬性是否應該組合成一個混合器,一條經驗法則就是你可否爲這個混合器想出一個好的名字。若是你能找到一個很好的短名字來描述這些屬性修飾的樣式,好比rounded-corners
fancy-font
或者no-bullets
,那麼每每可以構造一個合適的混合器。若是你找不到,這時候構造一個混合器可能並不合適。
混合器在某些方面跟css
類很像。都是讓你給一大段樣式命名,因此在選擇使用哪一個的時候可能會產生疑惑。最重要的區別就是類名是在html
文件中應用的,而混合器是在樣式表中應用的。這就意味着類名具備語義化含義,而不只僅是一種展現性的描述:用來描述html
元素的含義而不是html
元素的外觀。而另外一方面,混合器是展現性的描述,用來描述一條css
規則應用以後會產生怎樣的效果。
在以前的例子中,.notice
是一個有語義的類名。若是一個html
元素有一個notice
的類名,就代表了這個html
元素的用途:向用戶展現提醒信息。rounded-corners
混合器是展現性的,它描述了包含它的css
規則最終的視覺樣式,尤爲是邊框角的視覺樣式。混合器和類配合使用寫出整潔的html
和css
,由於使用語義化的類名亦能夠幫你避免重複使用混合器。爲了保持你的html
和css
的易讀性和可維護性,在寫樣式的過程當中必定要銘記兩者的區別。
有時候僅僅把屬性放在混合器中還遠遠不夠,可喜的是,sass
一樣容許你把css
規則放在混合器中。
混合器中不只能夠包含屬性,也能夠包含css
規則,包含選擇器和選擇器中的屬性,以下代碼:
@mixin no-bullets { list-style: none; li { list-style-image: none; list-style-type: none; margin-left: 0px; } }
當一個包含css
規則的混合器經過@include
包含在一個父規則中時,在混合器中的規則最終會生成父規則中的嵌套規則。舉個例子,看看下邊的sass
代碼,這個例子中使用了no-bullets
這個混合器:
ul.plain { color: #444; @include no-bullets; }
sass
的@include
指令會將引入混合器的那行代碼替換成混合器裏邊的內容。最終,上邊的例子以下代碼:
ul.plain { color: #444; list-style: none; } ul.plain li { list-style-image: none; list-style-type: none; margin-left: 0px; }
混合器中的規則甚至可使用sass
的父選擇器標識符&
。使用起來跟不用混合器時同樣,sass
解開嵌套規則時,用父規則中的選擇器替代&
。
若是一個混合器只包含css
規則,不包含屬性,那麼這個混合器就能夠在文檔的頂部調用,寫在全部的css
規則以外。若是你只是爲本身寫一些混合器,這並無什麼大的用途,可是當你使用一個相似於Compass
的庫時,你會發現,這是提供樣式的好方法,緣由在於你能夠選擇是否使用這些樣式。
接下來你將學習如何經過給混合器傳參數來讓混合器變得更加靈活和可重用。
混合器並不必定總得生成相同的樣式。能夠經過在@include
混合器時給混合器傳參,來定製混合器生成的精確樣式。當@include
混合器時,參數其實就是能夠賦值給css
屬性值的變量。若是你寫過JavaScript
,這種方式跟JavaScript
的function
很像:
@mixin link-colors($normal, $hover, $visited) { color: $normal; &:hover { color: $hover; } &:visited { color: $visited; } }
當混合器被@include
時,你能夠把它看成一個css
函數來傳參。若是你像下邊這樣寫:
a { @include link-colors(blue, red, green); } //Sass最終生成的是: a { color: blue; } a:hover { color: red; } a:visited { color: green; }
當你@include混合器時,有時候可能會很難區分每一個參數是什麼意思,參數之間是一個什麼樣的順序。爲了解決這個問題,sass
容許經過語法$name: value
的形式指定每一個參數的值。這種形式的傳參,參數順序就沒必要再在意了,只須要保證沒有漏掉參數便可:
a { @include link-colors( $normal: blue, $visited: green, $hover: red ); }
儘管給混合器加參數來實現定製很好,可是有時有些參數咱們沒有定製的須要,這時候也須要賦值一個變量就變成很痛苦的事情了。因此sass
容許混合器聲明時給參數賦默認值。
爲了在@include
混合器時沒必要傳入全部的參數,咱們能夠給參數指定一個默認值。參數默認值使用$name: default-value
的聲明形式,默認值能夠是任何有效的css
屬性值,甚至是其餘參數的引用,以下代碼:
@mixin link-colors( $normal, $hover: $normal, $visited: $normal ) { color: $normal; &:hover { color: $hover; } &:visited { color: $visited; } }
若是像下邊這樣調用:@include link-colors(red)
$hover
和$visited
也會被自動賦值爲red
。
混合器只是sass
樣式重用特性中的一個。咱們已經瞭解到混合器主要用於樣式展現層的重用,若是你想重用語義化的類呢?這就涉及sass
的另外一個重要的重用特性:選擇器繼承。
使用sass
的時候,最後一個減小重複的主要特性就是選擇器繼承。基於Nicole Sullivan
面向對象的css
的理念,選擇器繼承是說一個選擇器能夠繼承爲另外一個選擇器定義的全部樣式。這個經過@extend
語法實現,以下代碼:
//經過選擇器繼承繼承樣式 .error { border: 1px red; background-color: #fdd; } .seriousError { @extend .error; border-width: 3px; }
在上邊的代碼中,.seriousError
將會繼承樣式表中任何位置處爲.error
定義的全部樣式。以class="seriousError"
修飾的html
元素最終的展現效果就好像是class="seriousError error"
。相關元素不只會擁有一個3px
寬的邊框,並且這個邊框將變成紅色的,這個元素同時還會有一個淺紅色的背景,由於這些都是在.error
裏邊定義的樣式。
.seriousError
不只會繼承.error
自身的全部樣式,任何跟.error
有關的組合選擇器樣式也會被.seriousError
以組合選擇器的形式繼承,以下代碼:
//.seriousError從.error繼承樣式 .error a{ //應用到.seriousError a color: red; font-weight: 100; } h1.error { //應用到hl.seriousError font-size: 1.2rem; }
如上所示,在class="seriousError"
的html
元素內的超連接也會變成紅色和粗體。
本節將介紹與混合器相比,哪一種狀況下更適合用繼承。接下來在探索繼承的工做細節以前,咱們先了解一下繼承的高級用法。最後,咱們將看看使用繼承可能會有哪些坑,學習如何避免這些坑。
5-1節介紹了混合器主要用於展現性樣式的重用,而類名用於語義化樣式的重用。由於繼承是基於類的(有時是基於其餘類型的選擇器),因此繼承應該是創建在語義化的關係上。當一個元素擁有的類(好比說.seriousError
)代表它屬於另外一個類(好比說.error
),這時使用繼承再合適不過了。
這有點抽象,因此咱們從幾個方面來闡釋一下。想象一下你正在編寫一個頁面,給html
元素添加類名,你發現你的某個類(好比說.seriousError
)另外一個類(好比說.error
)的細化。你會怎麼作?
sass
時,咱們提倡的就是不要作重複的工做。.error
.seriousError
)給這兩個選擇器寫相同的樣式。若是.error的全部樣式都在同一個地方,這種作法很好,可是若是是分散在樣式表的不一樣地方呢?再這樣作就困難多了。.error
的樣式修飾遍及樣式表中各處時,這種作法面臨着跟使用選擇器組同樣的問題。這兩個類也不是剛好有相同的 樣式。你應該更清晰地表達這種關係。@extend
。讓.seriousError
從.error
繼承樣式,使二者之間的關係很是清晰。更重要的是不管你在樣式表的哪裏使用.error
.seriousError
都會繼承其中的樣式。如今你已經更好地掌握了什麼時候使用繼承,以及繼承有哪些突出的優勢,接下來咱們看看一些高級用法。
任何css
規則均可以繼承其餘規則,幾乎任何css
規則也均可以被繼承。大多數狀況你可能只想對類使用繼承,可是有些場合你可能想作得更多。最經常使用的一種高級用法是繼承一個html
元素的樣式。儘管默認的瀏覽器樣式不會被繼承,由於它們不屬於樣式表中的樣式,可是你對html
元素添加的全部樣式都會被繼承。
接下來的這段代碼定義了一個名爲disabled
的類,樣式修飾使它看上去像一個灰掉的超連接。經過繼承a這一超連接元素來實現:
.disabled { color: gray; @extend a; }
假如一條樣式規則繼承了一個複雜的選擇器,那麼它只會繼承這個複雜選擇器命中的元素所應用的樣式。舉例來講, 若是.seriousError
@extend
.important.error
, 那麼.important.error
和h1.important.error
的樣式都會被.seriousError
繼承, 可是.important
或者.error下
的樣式則不會被繼承。這種狀況下你極可能但願.seriousError
可以分別繼承.important
或者.error
下的樣式。
若是一個選擇器序列(#main .seriousError
)@extend
另外一個選擇器(.error
),那麼只有徹底命中#main .seriousError
這個選擇器的元素纔會繼承.error
的樣式,就像單個類 名繼承那樣。擁有class="seriousError"
的.main
元素以外的元素不會受到影響。
像#main .error
這種選擇器序列是不能被繼承的。這是由於從#main .error
中繼承的樣式通常狀況下會跟直接從.error
中繼承的樣式基本一致,細微的區別每每令人迷惑。
如今你已經瞭解了經過繼承可以作些什麼事情,接下來咱們將學習繼承的工做細節,在生成對應css
的時候,sass
具體幹了些什麼事情。
跟變量和混合器不一樣,繼承不是僅僅用css
樣式替換@extend處的代碼那麼簡單。爲了避免讓你對生成的css
感受奇怪,對這背後的工做原理有必定了解是很是重要的。
@extend
背後最基本的想法是,若是.seriousError @extend .error
, 那麼樣式表中的任何一處.error
都用.error
.seriousError
這一選擇器組進行替換。這就意味着相關樣式會如預期那樣應用到.error
和.seriousError
。當.error
出如今複雜的選擇器中,好比說h1.error
.error a
或者#main .sidebar input.error[type="text"]
,那狀況就變得複雜多了,可是不用擔憂,sass
已經爲你考慮到了這些。
關於@extend
有兩個要點你應該知道。
css
代碼相對更少。由於繼承僅僅是重複選擇器,而不會重複屬性,因此使用繼承每每比混合器生成的css
體積更小。若是你很是關心你站點的速度,請牢記這一點。css
層疊的規則。當兩個不一樣的css
規則應用到同一個html
元素上時,而且這兩個不一樣的css
規則對同一屬性的修飾存在不一樣的值,css
層疊規則會決定應用哪一個樣式。至關直觀:一般權重更高的選擇器勝出,若是權重相同,定義在後邊的規則勝出。混合器自己不會引發css
層疊的問題,由於混合器把樣式直接放到了css
規則中,而繼承存在樣式層疊的問題。被繼承的樣式會保持原有定義位置和選擇器權重不變。一般來講這並不會引發什麼問題,可是知道這點總沒有壞處。
一般使用繼承會讓你的css
美觀、整潔。由於繼承只會在生成css
時複製選擇器,而不會複製大段的css
屬性。可是若是你不當心,可能會讓生成的css
中包含大量的選擇器複製。
避免這種狀況出現的最好方法就是不要在css
規則中使用後代選擇器(好比.foo .bar
)去繼承css
規則。若是你這麼作,同時被繼承的css
規則有經過後代選擇器修飾的樣式,生成css
中的選擇器的數量很快就會失控:
.foo .bar { @extend .baz; } .bip .baz { a: b; }
在上邊的例子中,sass
必須保證應用到.baz的樣式同時也要應用到.foo .bar
(位於class="foo"的元素內的class="bar"的元素)。例子中有一條應用到.bip .baz
(位於class="bip"的元素內的class="baz"的元素)的css
規則。當這條規則應用到.foo .bar
時,可能存在三種狀況,以下代碼:
<!-- 繼承可能迅速變複雜 --> <!-- Case 1 --> <div class="foo"> <div class="bip"> <div class="bar">...</div> </div> </div> <!-- Case 2 --> <div class="bip"> <div class="foo"> <div class="bar">...</div> </div> </div> <!-- Case 3 --> <div class="foo bip"> <div class="bar">...</div> </div>
爲了應付這些狀況,sass
必須生成三種選擇器組合(僅僅是.bip .foo .bar不能覆蓋全部狀況)。若是任何一條規則裏邊的後代選擇器再長一點,sass
須要考慮的狀況就會更多。實際上sass
並不老是會生成全部可能的選擇器組合,即便是這樣,選擇器的個數依然可能會變得至關大,因此若是容許,儘量避免這種用法。
值得一提的是,只要你想,你徹底能夠放心地繼承有後代選擇器修飾規則的選擇器,無論後代選擇器多長,但有一個前提就是,不要用後代選擇器去繼承。
本文介紹了sass
最基本部分,你能夠輕鬆地使用sass
編寫清晰、無冗餘、語義化的css
。對於sass
提供的工具你已經有了一個比較深刻的瞭解,同時也掌握了什麼時候使用這些工具的指導原則。
變量是sass
提供的最基本的工具。經過變量可讓獨立的css
值變得可重用,不管是在一條單獨的規則範圍內仍是在整個樣式表中。變量、混合器的命名甚至sass
的文件名,能夠互換通用_
和-
。一樣基礎的是sass
的嵌套機制。嵌套容許css
規則內嵌套css
規則,減小重複編寫經常使用的選擇器,同時讓樣式表的結構一眼望去更加清晰。sass
同時提供了特殊的父選擇器標識符&
,經過它能夠構造出更高效的嵌套。
你也已經學到了sass
的另外一個重要特性,樣式導入。經過樣式導入能夠把分散在多個sass
文件中的內容合併生成到一個css
文件,避免了項目中有大量的css
文件經過原生的css
@import
帶來的性能問題。經過嵌套導入和默認變量值,導入能夠構建更強有力的、可定製的樣式。混合器容許用戶編寫語義化樣式的同時避免視覺層面上樣式的重複。你不只學到了如何使用混合器減小重複,同時學習到了如何使用混合器讓你的css
變得更加可維護和語義化。最後,咱們學習了與混合器相輔相成的選擇器繼承。繼承容許你聲明類之間語義化的關係,經過這些關係能夠保持你的css
的整潔和可維護性。