Sass應(yīng)用之實(shí)現(xiàn)主題切換
作者:瑪爾斯通
來(lái)源:SegmentFault 思否社區(qū)
背景
前置知識(shí)
variable mixin map
本質(zhì)
Sass作為CSS預(yù)處理器,需要編譯成CSS后,才能被瀏覽器識(shí)別和解析。因此無(wú)法在瀏覽器中直接使用Sass實(shí)現(xiàn)類似CSS變量那種動(dòng)態(tài)切換。本質(zhì)上來(lái)說(shuō),項(xiàng)目中有幾個(gè)主題就要提前定義好幾份主題樣式并全部引入。
思路
<html>
<div class="app" data-theme="light"></div>
</html>
.app {
&[data-theme='light'] {
color: #333;
}
&[data-theme='dark'] {
color: #fff;
}
}
實(shí)現(xiàn)
基礎(chǔ)版
<div id="app" class="app">
<h1 class="title">Hello, World</h1>
<p class="subtitle">當(dāng)前主題:<span id="theme-current">亮色</span></p>
<button class="theme-switch light" data-theme="light">亮色</button>
<button class="theme-switch dark" data-theme="dark">暗色</button>
</div>
<body data-theme="light">
<div class="app"></div>
</body>// 所有主題樣式
$bg-color-light: #ffffff;
$bg-color-dark: #091a28;
$title-color-light: #363636;
$title-color-dark: #ffffff;
$subtitle-color-light: #4a4a4a;
$subtitle-color-dark: cyan;
.app {
// 默認(rèn)主題樣式(light主題)
background-color: $bg-color-light;
// dark主題
[theme='dark'] & {
background-color: $bg-color-dark;
}
}
.title {
color: $title-color-light;
[theme='dark'] & {
color: $title-color-dark;
}
}
.subtitle {
color: $subtitle-color-light;
[theme='dark'] & {
color: $subtitle-color-dark;
}
}
每個(gè)需要應(yīng)用主題樣式的CSS選擇器中,都要寫(xiě)一遍對(duì)應(yīng)主題需要的樣式,比較繁瑣 
如果有多個(gè)主題,代碼量會(huì)極具增加,并且很多都是重復(fù)的“模板代碼” 
進(jìn)階版
// 所有主題樣式
$bg-color: (
// 亮色
light: #fff,
// 暗色
dark: #091a28
);
$title-color: (
light: #363636,
dark: #ffffff
);
$subtitle-color: (
light: #4a4a4a,
dark: cyan
);
@mixin themify($key, $valueMap) {
// 默認(rèn)主題
#{$key}: map-get($valueMap, 'light');
// dark主題
[theme='dark'] & {
#{$key}: map-get($valueMap, 'dark');
}
}
.app {
@include themify('background-color', $bg-color);
}
.title {
@include themify('color', $title-color);
}
.subtitle {
@include themify('color', $subtitle-color);
}
@mixin themify($key, $valueMap) {
// light主題
#{$key}: map-get($valueMap, 'light');
// dark主題
[theme='dark'] & {
#{$key}: map-get($valueMap, 'dark');
}
// dark1主題
[theme='dark1'] & {
#{$key}: map-get($valueMap, 'dark1');
}
// dark2主題
[theme='dark2'] & {
#{$key}: map-get($valueMap, 'dark2');
}
}
@mixin themify($key, $valueMap) {
// theme list
$themes: light, dark;
@each $theme in $themes {
[theme=#{$theme}] & {
#{$key}: map-get($valueMap, $theme);
}
}
}
https://codepen.io/Tom_chao/pen/YzrEVZY
總結(jié)
Sass作為一款流行的CSS預(yù)處理器,提供了插值表達(dá)#{}和map類型等特性,在實(shí)現(xiàn)主題切換方面提供了不少便利。
如果有多條主題樣式需要應(yīng)用,每一條都要寫(xiě)一遍@include,感覺(jué)有點(diǎn)麻煩,能不能只寫(xiě)一遍@include?
.app {
@include themify('background-color', $bg-color);
@include themify('color', $text-color);
// ...
}
// 希望可以只寫(xiě)一遍@include
.app {
@include themify(
(
'background-color': $bg-color,
'color': $text-color
)
);
}
如果還需要使用!important去覆蓋一些因?yàn)闄?quán)重問(wèn)題無(wú)法應(yīng)用的樣式(比如使用了外部UI庫(kù),外部UI庫(kù)中使用了!important,需要覆蓋該樣式),怎么解決?
// 這里提供一個(gè)思路,可以添加一個(gè)參數(shù)$important
@mixin themify($key, $valueMap: null, $important: false) {
// xxx
}

評(píng)論
圖片
表情

