使用 Sass 進行主題化:SCSS 教程
已發表: 2022-03-11使用 Sass 進行樣式表開發,即使使用其最基本的功能,如嵌套屬性或變量,也可以節省寶貴的時間,並使前端開發人員的工作更輕鬆。 毫不奇怪,CSS 預處理器已被廣泛用作為網站和應用程序創建樣式的實際方式。 我們簡直不能沒有他們了。
談到主題; 也就是說,在保持網站佈局的同時改變網站的外觀和感覺,Sass 的特性——比如 mixin 或函數——感覺就像坐飛機而不是走路! 在本 SCSS 教程中,我們將創建一個最小主題並使用 SCSS 為我們的 CSS 編程提供一些超能力。
一個基本的 Mixin 方法
假設我們有以下佈局:
<body class="theme-1"> <div class="container"> <div class="left"> Left </div> <div class="right"> Right <button class="button">Button</button> </div> </div> </body> </html>
我們被要求為其創建多個主題。 主題必須更改所有容器(包括主容器)和按鈕的顏色,主題將由主體中的類確定,或者它也可以是“外部”容器:
<body class="theme-1">
讓我們構建一個名為“themable”的mixin,它將包含我們的配色方案作為參數。
@mixin themable($theme-name, $container-bg, $left-bg, $right-bg, $innertext, $button-bg) { .#{$theme-name} { .container { background-color: $container-bg; border: 1px solid #000; display: flex; height: 500px; justify-content: space-between; margin: 0 auto; padding: 1em; width: 50%; * { color: $innertext; font-size: 2rem; } .left { background-color: $left-bg; height: 100%; width: 69%; } .right { background-color: $right-bg; height: 100%; position: relative; width: 29%; } .button { background-color: $button-bg; border: 0; border-radius: 10px; bottom: 10px; cursor: pointer; font-size: 1rem; font-weight: bold; padding: 1em 2em; position: absolute; right: 10px; } } } }
然後用它來生成我們的主題:
@include themable(theme-1, #f7eb80, #497265, #82aa91, #fff, #bc6a49); @include themable(theme-2, #e4ada7, #d88880, #cc6359, #fff, #481b16);
至此,我們已經節省了很多時間,但是這種方式存在一些問題:
除了顏色之外,主題通常還有很多不同的屬性。 例如,如果我們想修改 Bootstrap 主題,那麼按照之前的“配方”編寫一個 mixin 將難以維護,代碼也難以閱讀。 另外,我們並沒有真正遵循 Sass 最佳實踐——例如,將十六進制顏色代碼直接輸入到 mixin 中。
使用 Sass Map 設計樣式方案
借助主要類似於鍵索引數組的地圖,我們可以為我們的主題構建更語義化、更有意義的樣式集,這將更容易被我們的同事開發人員維護和理解。 我們也可以使用列表,但就我個人而言,我發現地圖更適合此目的。 列表沒有鍵,而鍵是不言自明的。
我們新方法的映射將是一個嵌套映射:
$theme-1: ( container: ( bg: #e4ada7, color: #000, border-color: #000 ), left: ( bg: #d88880, color: #fff, height: 100%, width: 69% ), right: ( bg: #cc6359, color: #fff, height: 100%, width: 29% ), button: ( bg: #481b16, color: #fff ) );
如果我們想訪問我們的方案theme-1
及其子映射的每個部分,我們使用@each
指令來循環它們中的每一個:

@each $section, $map in $theme-1
$section
將返回當前部分的鍵, $map
將返回與該鍵對應的嵌套映射。
然後,我們可以使用map-get
函數訪問每個地圖的屬性,比如背景(bg)屬性:
map-get($map, bg)
最後,結合我們的新 mixin,基於我們的地圖結構,我們可以創建任意數量的主題:
@mixin themable($theme-name, $theme-map) { .#{$theme-name} { .container { .left, .right { font-size: 2rem; } } .container .right { position: relative } .button { border: 0; border-radius: 10px; bottom: 10px; cursor: pointer; font-size: 1rem; font-weight: bold; padding: 1em 2em; position: absolute; right: 10px; } // Loop through each of the keys (sections) @each $section, $map in $theme-map { @if ($section == container) { .container { background-color: map-get($map, bg); border: 1px solid map-get($map, border-color); display: flex; height: 500px; justify-content: space-between; margin: 0 auto; padding: 1em; width: 50%; } } @else { .#{$section} { background-color: map-get($map, bg); color: map-get($map, color); @if ($section != button) { height: map-get($map, height); width: map-get($map, width); } } } } } } @include themable(theme-1, $theme-1); @include themable(theme-2, $theme-2); … …
請注意,我們還使用@if
指令來區分非按鈕部分的屬性。
@if ($section != button) { height: map-get($map, height); width: map-get($map, width); }
這樣,我們可以為某些部分添加不同的屬性以創建特定的屬性甚至規則,或者我們可以區分具有單個值的鍵和具有嵌套映射的另一個鍵。
我們的主題還可以由多個混入使用的許多映射組成,應用於樣式表的不同部分。 這完全取決於我們基本佈局的複雜性,當然還有我們個人的方法。
進一步優化
Sass 提供了有用的內置函數來為我們節省更多的工作; 例如,hsl 函數如lighten
或darken
來計算,例如,懸停在按鈕上時按鈕的顏色。
我們可以修改按鈕代碼以在懸停時使其背景變亮,而不考慮原始背景顏色。 這樣,我們不必為此狀態添加另一種顏色。
@if ($section != button) { height: map-get($map, height); width: map-get($map, width); } @else { &:hover { background-color: lighten(map-get($map, bg), 20%); } }
此外,通過使用 Sass 模塊,我們的代碼可以更加清晰和可擴展; 每個主題圖都可以包含在一個模塊中,然後導入到我們的主樣式表中。
@import 'theme-1'; @import 'theme-2'; @import 'theme-3'; … … @mixin themable($theme-name, $theme-map) { .#{$theme-name} { .container { … …
這將要求將模塊放置在項目中,如下所示:
/ ├── _theme-1.scss ├── _theme-2.scss └── _theme-2.scss
如果您有興趣了解有關使用 Sass 乾燥 CSS 的更多信息,Toptaler Justin Brazeau 和 Sass 愛好者在他的精彩文章Sass Mixins: Keep Your Stylesheets DRY中討論了這一點。