變量是任何編程語言的精髓。變量讓值得以重用,避免了一遍遍地復(fù)制副本。最重要的是,使用變量讓更新一個值變得很方便。不用查找、替換,更不用手動檢索。
然而CSS是一個將所有雞蛋裝在一個大籃子中的語言,不同于其他語言,這里沒有真正的作用域。因此,我們需要十分重視由于添加變量而引起的沖突。
我的建議只適用于創(chuàng)建變量并感覺確有必要的情況下。不要為了某些駭客行為而聲明新變量,這絲毫沒有作用。只有滿足所有下述標(biāo)準(zhǔn)時方可創(chuàng)建新變量:
基本上,沒有理由聲明一個永遠(yuǎn)不需要更新或者只在單一地方使用變量。
Sass 中變量的作用域在過去幾年已經(jīng)發(fā)生了一些改變。直到最近,規(guī)則集和其他范圍內(nèi)聲明變量的作用域才默認(rèn)為本地。如果已經(jīng)存在同名的全局變量,則局部變量覆蓋全局變量。從 Sass 3.4 版本開始,Sass 已經(jīng)可以正確處理作用域的概念,并通過創(chuàng)建一個新的局部變量來代替。
本部分討論下全局變量的影子。當(dāng)在局部范圍內(nèi)(選擇器內(nèi)、函數(shù)內(nèi)、混合宏內(nèi)……)聲明一個已經(jīng)存在于全局范圍內(nèi)的變量時,局部變量就成為了全局變量的影子?;旧?,局部變量只會在局部范圍內(nèi)覆蓋全局變量。
以下代碼片可以解析變量影子的概念。
// Initialize a global variable at root level.
$variable: 'initial value';
// Create a mixin that overrides that global variable.
@mixin global-variable-overriding {
$variable: 'mixin value' !global;
}
.local-scope::before {
// Create a local variable that shadows the global one.
$variable: 'local value';
// Include the mixin: it overrides the global variable.
@include global-variable-overriding;
// Print the variable’s value.
// It is the **local** one, since it shadows the global one.
content: $variable;
}
// Print the variable in another selector that does no shadowing.
// It is the **global** one, as expected.
.other-local-scope::before {
content: $variable;
}
!default
標(biāo)識符如果創(chuàng)建一個庫、框架、柵格系統(tǒng)甚至任何的 Sass 片段,是為了分發(fā)經(jīng)驗(yàn)或者被其他開發(fā)者使用,那么與之配置的所有變量都應(yīng)該使用 !default
標(biāo)志來定義,方便其他開發(fā)者重寫變量。
$baseline: 1em !default;
多虧如此,開發(fā)者才能在引入你的庫之前定義自用的 $baseline
,引入后又不必?fù)?dān)心自己的值被重定義了。
// Developer’s own variable
$baseline: 2em;
// Your library declaring `$baseline`
@import 'your-library';
// $baseline == 2em;
!global
標(biāo)識符!global
標(biāo)志應(yīng)該只在局部范圍的全局變量被覆蓋時使用。定義根級別的變量時,!global
標(biāo)志應(yīng)該省略。
// Yep
$baseline: 2em;
// Nope
$baseline: 2em !global;
使用 maps 比使用多個不同的變量有明顯優(yōu)勢。最重要的優(yōu)勢就是 map 的遍歷功能,這在多個不同變量中是不可能實(shí)現(xiàn)的。
另一個支持使用 map 的原因,是它可以創(chuàng)建 map-get()
函數(shù)以提供友好 API 的功能。比如,思考一下下述 Sass 代碼:
/// Z-indexes map, gathering all Z layers of the application
/// @access private
/// @type Map
/// @prop {String} key - Layer’s name
/// @prop {Number} value - Z value mapped to the key
$z-indexes: (
'modal': 5000,
'dropdown': 4000,
'default': 1,
'below': -1,
);
/// Get a z-index value from a layer name
/// @access public
/// @param {String} $layer - Layer’s name
/// @return {Number}
/// @require $z-indexes
@function z($layer) {
@return map-get($z-indexes, $layer);
}