混合宏-聲明混合宏
如果你的整個網站中有幾處小樣式類似,比如顏色,字體等,在 Sass 可以使用變量來統一處理,那么這種選擇還是不錯的。但當你的樣式變得越來越復雜,需要重復使用大段的樣式時,使用變量就無法達到我們目了。這個時候 Sass 中的混合宏就會變得非常有意義。
1、聲明混合宏
不帶參數混合宏:
在 Sass 中,使用“@mixin”來聲明一個混合宏。如:
1 @mixin border-radius{
2 -webkit-border-radius: 5px;
3 border-radius: 5px;
4 }
其中 @mixin 是用來聲明混合宏的關鍵詞,有點類似 CSS 中的 @media、@font-face 一樣。border-radius 是混合宏的名稱。大括號里面是復用的樣式代碼。
帶參數混合宏:
除了聲明一個不帶參數的混合宏之外,還可以在定義混合宏時帶有參數,如:
1 @mixin border-radius($radius:5px){
2 -webkit-border-radius: $radius;
3 border-radius: $radius;
4 }
復雜的混合宏:
上面是一個簡單的定義混合宏的方法,Sass 中的混合宏還提供更為復雜的,你可以在大括號里面寫上帶有邏輯關系,幫助更好的做你想做的事情,如:
1 @mixin box-shadow($shadow...) {
2 @if length($shadow) >= 1 { 3 @include prefixer(box-shadow, $shadow);
4 } @else{
5 $shadow:0 0 4px rgba(0,0,0,.3);
6 @include prefixer(box-shadow, $shadow);
7 }
8 }
這個 box-shadow 的混合宏,帶有多個參數,這個時候可以使用“ … ”來替代。簡單的解釋一下,當 $shadow 的參數數量值大於或等於“ 1 ”時,表示有多個陰影值,反之調用默認的參數值“ 0 0 4px rgba(0,0,0,.3) ”。
混合宏-調用混合宏
在 Sass 中通過 @mixin 關鍵詞聲明了一個混合宏,那么在實際調用中,其匹配了一個關鍵詞“@include”來調用聲明好的混合宏。
1 @mixin border-radius{
2 -webkit-border-radius: 3px;
3 border-radius: 3px;
4 }
在一個按鈕中要調用定義好的混合宏“border-radius”,可以這樣使用:
1 button {
2 @include border-radius; 3 }
這個時候編譯出來的 CSS:
1 button {
2 -webkit-border-radius: 3px;
3 border-radius: 3px;
4 }
混合宏的參數--傳一個不帶值的參數
Sass 的混合宏,可以傳參,在 Sass 中傳參主要有以下幾種情形:
A) 傳一個不帶值的參數
在混合宏中,可以傳一個不帶任何值的參數。
1 @mixin border-radius($radius){
2 -webkit-border-radius: $radius;
3 border-radius: $radius;
4 }
在混合宏“border-radius”中定義了一個不帶任何值的參數“$radius”。
在調用的時候可以給這個混合宏傳一個參數值:
1 .box{
2 @include border-radius(3px);
3 }
這里表示給混合宏傳遞一個“border-radius”的值為“3px”。
編譯出來的CSS:
1 .box {
2 -webkit-border-radius: 3px;
3 border-radius: 3px;
4 }
混合宏的參數--傳一個帶值的參數
在 Sass 的混合宏中,還可以給混合宏的參數傳一個默認值,例如:
1 @mixin border-radius($radius:3px){
2 -webkit-border-radius: $radius;
3 border-radius: $radius;
4 }
在混合宏“border-radius”傳了一個參數“$radius”,而且給這個參數賦予了一個默認值“3px”。
在調用類似這樣的混合宏時,會多有一個機會,假設你的頁面中的圓角很多地方都是“3px”的圓角,那么這個時候只需要調用默認的混合宏“border-radius”:
1 .btn {
2 @include border-radius; 3 }
編譯出來的 CSS:
1 .btn {
2 -webkit-border-radius: 3px;
3 border-radius: 3px;
4 }
但有的時候,頁面中有些元素的圓角值不一樣,那么可以隨機給混合宏傳值,如:
1 .box {
2 @include border-radius(50%); 3 }
編譯出來的 CSS:
1 .box {
2 -webkit-border-radius: 50%;
3 border-radius: 50%;
4 }
混合宏的參數--傳多個參數
Sass 混合宏除了能傳一個參數之外,還可以傳多個參數,如:
1 @mixin center($width,$height){
2 width: $width;
3 height: $height;
4 position: absolute;
5 top: 50%;
6 left: 50%;
7 margin-top: -($height) / 2;
8 margin-left: -($width) / 2;
9 }
在混合宏“center”就傳了多個參數。在實際調用和其調用其他混合宏是一樣的:
1 .box-center {
2 @include center(500px,300px); 3 }
編譯出來 CSS:
.box-center { width: 500px; height: 300px; position: absolute; top: 50%; left: 50%; margin-top: -150px; margin-left: -250px;
}
有一個特別的參數“…”。當混合宏傳的參數過多之時,可以使用參數來替代,如:
1 @mixin box-shadow($shadows...){
2 @if length($shadows) >= 1 { 3 -webkit-box-shadow: $shadows;
4 box-shadow: $shadows;
5 } @else {
6 $shadows: 0 0 2px rgba(#000,.25);
7 -webkit-box-shadow: $shadow;
8 box-shadow: $shadow;
9 }
10 }
在實際調用中:
1 .box {
2 @include box-shadow(0 0 1px rgba(#000,.5),0 0 2px rgba(#000,.2)); 3 }
編譯出來的CSS:
1 .box {
2 -webkit-box-shadow: 0 0 1px rgba(0, 0, 0, 0.5), 0 0 2px rgba(0, 0, 0, 0.2);
3 box-shadow: 0 0 1px rgba(0, 0, 0, 0.5), 0 0 2px rgba(0, 0, 0, 0.2);
4 }
混合宏的參數--混合宏的不足
混合宏在實際編碼中給我們帶來很多方便之處,特別是對於復用重復代碼塊。但其最大的不足之處是會生成冗余的代碼塊。比如在不同的地方調用一個相同的混合宏時。如:
1 @mixin border-radius{
2 -webkit-border-radius: 3px;
3 border-radius: 3px;
4 }
5
6 .box {
7 @include border-radius; 8 margin-bottom: 5px;
9 }
10
11 .btn {
12 @include border-radius; 13 }
示例在“.box”和“.btn”中都調用了定義好的“border-radius”混合宏。先來看編譯出來的 CSS:
1 .box {
2 -webkit-border-radius: 3px;
3 border-radius: 3px;
4 margin-bottom: 5px;
5 }
6
7 .btn {
8 -webkit-border-radius: 3px;
9 border-radius: 3px;
10 }
Sass 在調用相同的混合宏時,並不能智能的將相同的樣式代碼塊合並在一起。這也是 Sass 的混合宏最不足之處。
擴展/繼承(@extend)
在 Sass 中繼承類中的樣式代碼塊。在 Sass 中是通過關鍵詞 “@extend”來繼承已存在的類樣式塊,從而實現代碼的繼承。如下所示:
1 //SCSS 2 .btn {
3 border: 1px solid #ccc;
4 padding: 6px 10px;
5 font-size: 14px;
6 }
7 .btn-primary {
8 background-color: #f36;
9 color: #fff;
10 @extend .btn; 11 }
12 .btn-second {
13 background-color: orange;
14 color: #fff;
15 @extend .btn; 16 }
編譯出來之后:
1 //CSS 2 .btn, .btn-primary, .btn-second {
3 border: 1px solid #ccc;
4 padding: 6px 10px;
5 font-size: 14px;
6 }
8 .btn-primary {
9 background-color: #f36;
10 color: #fff;
11 }
13 .btn-second {
14 background-clor: orange;
15 color: #fff;
16 }
從示例代碼可以看出,在 Sass 中的繼承,可以繼承類樣式塊中所有樣式代碼,而且編譯出來的 CSS 會將選擇器合並在一起,形成組合選擇器:
1 .btn, .btn-primary, .btn-second {
2 border: 1px solid #ccc;
3 padding: 6px 10px;
4 font-size: 14px;
5 }
占位符%placeholder
Sass 中的占位符 %placeholder 功能是一個很強大,很實用的一個功能,可以取代以前 CSS 中的基類造成的代碼冗余的情形。 %placeholder 聲明的代碼,如果不被 @extend 調用的話,不會產生任何代碼。
1 %mt5 {
2 margin-top: 5px;
3 }
4 %pt5{
5 padding-top: 5px;
6 }
這段代碼沒有被 @extend 調用,只有通過 @extend 調用才會產生代碼:
1 //SCSS 2 %mt5 {
3 margin-top: 5px;
4 }
5 %pt5{
6 padding-top: 5px;
7 }
8
9 .btn {
10 @extend %mt5; 11 @extend %pt5; 12 }
13
14 .block {
15 @extend %mt5; 16 span {
17 @extend %pt5; 18 }
19 }
編譯出來的CSS
1 //CSS 2 .btn, .block {
3 margin-top: 5px;
4 }
5 .btn, .block span {
6 padding-top: 5px;
7 }
通過 @extend 調用的占位符,編譯出來的代碼會將相同的代碼合並在一起。
混合宏 VS 繼承 VS 占位符
什么時候用混合宏,什么時候用繼承,什么時候使用占位符?
a)Sass中的混合宏使用


總結:不會自動合並相同的樣式代碼,如果在樣式文件中調用同一個混合宏,會產生多個對應的樣式代碼,造成代碼的冗余。他還可以傳參數。
如果你的代碼塊中涉及到變量,建議使用混合宏來創建相同的代碼塊。
b) Sass 中繼承


總結:使用繼承后,編譯出來的 CSS 會將使用繼承的代碼塊合並到一起,通過組合選擇器的方式展現,比如 .mt, .block, .block span, .header, .header span。這樣編譯出來的代碼相對於混合宏來說要干凈的多。但是他不能傳變量參數。
如果你的代碼塊不需要專任何變量參數,而且有一個基類已在文件中存在,那么建議使用 Sass 的繼承。
c) 占位符


總結:編譯出來的 CSS 代碼和使用繼承基本上是相同,只是不會在代碼中生成占位符 mt 的選擇器。那么占位符和繼承的主要區別的,“占位符是獨立定義,不調用的時候是不會在 CSS 中產生任何代碼;繼承是首先有一個基類存在,不管調用與不調用,基類的樣式都將會出現在編譯出來的 CSS 代碼中。”

