鍍金池/ 教程/ HTML/ 混合宏
簡介
語法格式
循環(huán)
響應(yīng)式設(shè)計和斷點
擴展
條件語句
結(jié)構(gòu)
注釋
工具
混合宏
變量
命名約定
警告和錯誤
總結(jié)概要

混合宏

混合宏是整個 Sass 語言中最常用的功能之一。這是重用和減少重復組件的關(guān)鍵。這么做有很棒的原因:混合宏允許開發(fā)者在樣式表中定義可復用樣式,減少了對非語義類的需求,比如.float-left。

它們可以包含所有的 CSS 規(guī)則,并且在 Sass 文檔允許的任何地方都表現(xiàn)良好。它們甚至可以像函數(shù)一樣接受參數(shù)。不用多說,充滿了無盡的可能。

不過我有必要提醒你濫用混合宏的破壞力量。再次重申一遍,使用混合宏的關(guān)鍵是簡潔。建立混入大量邏輯而極具力量的混合宏看上去確實很有誘惑力。這就是所謂的過度開發(fā),大多數(shù)開發(fā)者常常因此陷入困境。不要過度邏輯化你的代碼,盡量保持一切簡潔。如果一個混合宏最后超過了 20 行,那么它應(yīng)該被分離成更小的塊甚至是重建。

基礎(chǔ)

話雖如此,混合宏確實非常有用,你應(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;
  }
}

另一個有效的實例是通過在混合宏中綁定 widthheight 屬性,可以為元素設(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ù)量不明的參數(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 并不是總被支持的。如果你使用 BourbonCompass,你可能就已經(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 是一個更好地選擇。

上一篇:變量下一篇:命名約定