混合宏是整個 Sass 語言中最常用的功能之一。這是重用和減少重復組件的關(guān)鍵。這么做有很棒的原因:混合宏允許開發(fā)者在樣式表中定義可復用樣式,減少了對非語義類的需求,比如.float-left
。
它們可以包含所有的 CSS 規(guī)則,并且在 Sass 文檔允許的任何地方都表現(xiàn)良好。它們甚至可以像函數(shù)一樣接受參數(shù)。不用多說,充滿了無盡的可能。
不過我有必要提醒你濫用混合宏的破壞力量。再次重申一遍,使用混合宏的關(guān)鍵是簡潔。建立混入大量邏輯而極具力量的混合宏看上去確實很有誘惑力。這就是所謂的過度開發(fā),大多數(shù)開發(fā)者常常因此陷入困境。不要過度邏輯化你的代碼,盡量保持一切簡潔。如果一個混合宏最后超過了 20 行,那么它應(yīng)該被分離成更小的塊甚至是重建。
話雖如此,混合宏確實非常有用,你應(yīng)該學習使用它。經(jīng)驗告訴我們,如果你發(fā)現(xiàn)有一組 CSS 屬性經(jīng)常因同一個原因一起出現(xiàn)(非巧合),那么你就可以使用混合宏來代替。比如Nicolas Gallagher 的清除浮動應(yīng)當放入一個混合宏的實例。
/// Helper to clear inner floats
/// @author Nicolas Gallagher
/// @link http://nicolasgallagher.com/micro-clearfix-hack/ Micro Clearfix
@mixin clearfix {
&::after {
content: '';
display: table;
clear: both;
}
}
另一個有效的實例是通過在混合宏中綁定 width
和 height
屬性,可以為元素設(shè)置寬高。這樣不僅會淡化不同類型代碼間的差異,也便于閱讀。
/// Helper to size an element
/// @author Hugo Giraudel
/// @param {Length} $width
/// @param {Length} $height
@mixin size($width, $height: $width) {
width: $width;
height: $height;
}
更多復雜示例可以參考:《使用 Sass 混合宏創(chuàng)建三角形》, 《使用混合宏創(chuàng)建長陰影》 以及 《使用混合宏為低版本瀏覽器創(chuàng)建線性漸變》。
有時候我們使用混合宏只是為了避免重復聲明相同的樣式,這種情況下,往往不需要傳遞參數(shù)。所以,為了簡潔起見,我們可以刪除圓括號,使用 @include
關(guān)鍵字來表示當前行調(diào)用了混合宏。
// Yep
.foo {
@include center;
}
// Nope
.foo {
@include center();
}
當混合宏需要處理數(shù)量不明的參數(shù)時,通常使用 arglist
而不是列表??梢哉J為 arglist
是 Sass 中隱藏而未被記錄的第八個數(shù)據(jù)類型,通常當需要任意數(shù)量參數(shù)的時候,被隱式使用到參數(shù)中含有 ...
標志的混合宏和函數(shù)中。
@mixin shadows($shadows...) {
// type-of($shadows) == 'arglist'
// …
}
現(xiàn)在,當要建立一個接收多個參數(shù)(默認為 3 或者更多)的混合宏時,在將它們合并為列表或者 map 之前,要反復考量這樣做是否比一個個的單獨存在更易于使用。
Sass 的混合宏和函數(shù)聲明非常智能,你只需給函數(shù)/混合宏一個列表或 map,它會自動解析為一系列的參數(shù)。
@mixin dummy($a, $b, $c) {
// …
}
// Yep
@include dummy(true, 42, 'kittens');
// Yep but nope
$params: (true, 42, 'kittens');
$value: dummy(nth($params, 1), nth($params, 2), nth($params, 3));
// Yep
$params: (true, 42, 'kittens');
@include dummy($params...);
// Yep
$params: (
'c': 'kittens',
'a': true,
'b': 42,
);
@include dummy($params...);
更多有關(guān)多參數(shù)、列表參數(shù)的信息請參考這篇文章:Sass 中的不定參數(shù)和參數(shù)列表。
通過使用自定義混合宏來處理 CSS 中未被支持或部分支持的瀏覽器前綴,是非常有吸引力的一種做法。但我們不希望這么做。首先,如果你可以使用 Autoprefixer,那就使用它。它會從你的項目中移除Sass代碼,會一直更新并一定會進行比你手動添加前綴更棒的處理。
不幸的是,Autoprefixer 并不是總被支持的。如果你使用 Bourbon 或 Compass,你可能就已經(jīng)知道它們都提供了一個混合宏的集合,用來為你處理瀏覽器前綴,那就用它們吧。
如果你不能使用 Autoprefixe,甚至也不能使用 Bourbon 和 Compass,那么接下來唯一的方式,就是使用自己的混合宏處理帶有前綴的 CSS 屬性。但是,請不要為每個屬性建立混合宏,更不要無腦輸出每個瀏覽器的前綴(有些根本就不存在)。
// Nope
@mixin transform($value) {
-webkit-transform: $value;
-moz-transform: $value;
transform: $value;
}
比較好的做法是
/// Mixin helper to output vendor prefixes
/// @access public
/// @author HugoGiraudel
/// @param {String} $property - Unprefixed CSS property
/// @param {*} $value - Raw CSS value
/// @param {List} $prefixes - List of prefixes to output
@mixin prefix($property, $value, $prefixes: ()) {
@each $prefix in $prefixes {
-#{$prefix}-#{$property}: $value;
}
#{$property}: $value;
}
然后就可以非常簡單地使用混合宏了:
.foo {
@include prefix(transform, rotate(90deg), ('webkit', 'ms'));
}
請記住,這是一個糟糕的解決方案。例如,他不能處理那些需要復雜的前綴,比如 flexbox
。在這個意義上說,使用 Autoprefixer 是一個更好地選擇。