如果你也覺得 CSS 不容易維護重複使用、每次要定義比較深層 dom element 的樣式,CSS 要寫的超級長 ... 等一堆怨言,那一定要來寫寫看 SCSS!
在開始之前,執行下面指令讓 webpack 可以編譯 SCSS:
npm install sass-loader node-sass webpack --save-dev
另外,如果是在 component 的 <style>
中撰寫 SCSS 記得要加上 lang
的屬性如 <style lang="scss">
。
<template>
<div class="layer-01">
<div class="layer-02">
<div class="layer-03">
<div class="layer-04-01">
</div>
<div class="layer-04-02">
</div>
</div>
</div>
</div>
</template>
當我們要設定 layer-04-01
的樣式,原始寫法實在「不忍卒讀」 XD! 在 SCSS 中,一樣有階層觀念,所以會寫成下面的樣子:
.layer-01 {
.layer-02 {
.layer-03 {
.layer-04-01 {
color: #ff6666;
}
}
}
}
假設現在 layer-04-02
也要定義樣式,父節點就不用再寫過一次了,直接像 layer-04-01
一樣掛在 layer-03
底下即可。
// ...
.layer-03 {
.layer-04-01 {
color: #ff6666;
}
.layer-04-02 {
font-size: 18px;
}
}
// ...
比較需要注意的是偽元素 (pseudo element)
和偽類 (pseudo class)
(就是由冒號開頭的那些樣式設定如: :hover),要在前面加上「&
」。
// ...
.layer-04-01 {
color: #ff6666;
&:hover {
color: #00ccff;
}
}
// ...
在相同網站常有固定的系列顏色,或是在同一個頁面中有許多樣式的設定是相同的,過去最常寫的方法是將這些樣式寫在一個 class
底下,但是這樣的做法卻沒辦法讓部分的樣式值被動態計算。
在 SCSS 當中我們可以宣告變數啦,而且可以自由的進行運算! 宣告變數的方法為 $<變數名稱>
:
$base-font-size: 14px;
// ...
.layer-04-01 {
font-size: $base-font-size;
&:hover {
font-size: $base-font-size * 5;
}
}
// ...
如果是要將變數與其他變數進行類似字串相加,在使用上要用 #{變數}
的方式轉換出來:
$base-font-size: 14;
$hover-font-unit: '%';
// ...
.layer-04-01 {
font-size: #{$base-font-size}px;
&:hover {
font-size: #{$base-font-size * 15}#{$hover-font-unit};
}
}
// ...
跟寫程式一樣,變數之後就是 function,從上面的 .layer-04-01:hover
來看,假設有很多 dom element 的 font-size
有需要透過計算,我們可以寫成 @function
使用,要注意 @return
的結果只能是樣式的值。
$base-font-size: 14;
@function font-size-calc($times, $unit) {
@return #{$base-font-size * $times}#{$unit}
}
// ...
.layer-04-01 {
font-size: #{$base-font-size}px;
&:hover {
font-size: font-size-calc(15, '%');
}
}
// ...
懶惰如我,@function
只能回傳一個樣式值完全不能滿足啊! 有沒有辦法又有計算、又可以回傳許多樣式概念有點類似下面的 JS 範例呢?
const buttonStyle = (backgroundColor, iconSize, iconUnit) => {
retrun {
backgroundColor,
fontSize: `${iconSize * 5}${iconUnit}`,
borderRadius: '4px',
}
}
const fooButton = {
...buttonStyle('#aeaeae', 14, '%'),
// ...
}
有的!! SCSS 提供 @mixin
搭配 @include
的方法:
@mixin button-style ($background-color, $icon-size, $icon-unit) {
background-color: $background-color;
font-size: #{$icon-size}#{$icon-unit};
border-radius: 10px;
}
// ...
.layer-04-01 {
@include button-style(#ff6666, 14, 'px');
width: 100px;
color: #fff;
&:hover {
font-size: font-size-calc(15, '%');
}
}
跟 JS 一樣我們可以將其他 .scss
內的樣式匯入使用,使用的方式為 @import ".scss 檔案路徑"
@import "@/assets/scss/button.scss";
// ...
最後分享一下,最近在寫專案的一些心得,當我們在使用第三方 components 的時候,最大的問題大概是樣式不是那麼符合目前專案的風格,所以不得已要用其他套件或是自己重新造輪子。另外,目前多數的網站會有 DayNight theme 支持背景在亮色系與黑色系之間轉換,在轉換過程中,因為配色的關係,所以 component 的一些樣式需要調整。
在有了這些麻煩之後,在撰寫各個 component 的時候開始會將各個 component 顏色、背景相關部分的樣式獨立成 .scss
檔,未來如果 「版型不變
」 ,要更換顏色或是背景樣式就相對方便一些。
例如 DayNight theme 的部分,我們會把 components 顏色、背景相關寫到 day-theme.scss
和 night-theme.scss
,後續只要控制在最外層的 component (例如 layout),更換 css class name 的方式,下面所有 components 就可以去讀到對應的主題配色,即便今天更換了專案風格調整,樣式有些許的變動,都可以藉由類似這種方式調整與客製,當然,畢竟小弟不是專業 UI/UX 設計師,所以也還在學習,只是覺得這種可能會變動的樣式獨立拉出來,維護與運作上更加方便與舒服,有興趣的大大可以參考看看囉!
今天跟大家介紹基礎、常用的 SCSS 用法,讓我們在撰寫網站的時候更加方便好維護! 踩坑系列也差不多進入尾聲,明後兩天要帶大家將專案部屬到 docker
,完成 API 與 WEB 的網站架設!