iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 28
0
Modern Web

RRR撞到不負責之 Laravel + Nuxt.js 踩坑全紀錄系列 第 28

Day 28. 別鬧了,定義個樣式 class name 寫得有夠長 - SCSS 基礎介紹

如果你也覺得 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

跟寫程式一樣,變數之後就是 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, '%');
                }
            }
// ...

@mixin & @include

懶惰如我,@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, '%');
                }
            }

@import

跟 JS 一樣我們可以將其他 .scss 內的樣式匯入使用,使用的方式為 @import ".scss 檔案路徑"

@import "@/assets/scss/button.scss";

// ...

Theme

最後分享一下,最近在寫專案的一些心得,當我們在使用第三方 components 的時候,最大的問題大概是樣式不是那麼符合目前專案的風格,所以不得已要用其他套件或是自己重新造輪子。另外,目前多數的網站會有 DayNight theme 支持背景在亮色系與黑色系之間轉換,在轉換過程中,因為配色的關係,所以 component 的一些樣式需要調整。

在有了這些麻煩之後,在撰寫各個 component 的時候開始會將各個 component 顏色、背景相關部分的樣式獨立成 .scss 檔,未來如果 版型不變 ,要更換顏色或是背景樣式就相對方便一些。

例如 DayNight theme 的部分,我們會把 components 顏色、背景相關寫到 day-theme.scssnight-theme.scss,後續只要控制在最外層的 component (例如 layout),更換 css class name 的方式,下面所有 components 就可以去讀到對應的主題配色,即便今天更換了專案風格調整,樣式有些許的變動,都可以藉由類似這種方式調整與客製,當然,畢竟小弟不是專業 UI/UX 設計師,所以也還在學習,只是覺得這種可能會變動的樣式獨立拉出來,維護與運作上更加方便與舒服,有興趣的大大可以參考看看囉!


今天跟大家介紹基礎、常用的 SCSS 用法,讓我們在撰寫網站的時候更加方便好維護! 踩坑系列也差不多進入尾聲,明後兩天要帶大家將專案部屬到 docker,完成 API 與 WEB 的網站架設!


上一篇
Day 27. 居家旅行、殺人滅口,必備良藥 -「註冊」、「登入」與「登出」
下一篇
Day 29. 博大坑深的 Docker 部屬 - laradock (1/2)
系列文
RRR撞到不負責之 Laravel + Nuxt.js 踩坑全紀錄31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言