CSS 筆記 | Sass/SCSS

閱讀時間約 15 分鐘

最近感覺對 CSS 的熟悉程度大大上升了!但是發現我對 CSS 預處理器 (CSS Preprocessor) 還是停留在初見時的陌生,那種感覺大概就是我認識你,路上遇到你打個招呼然後就各奔東西了 XD

CSS 預處理器是什麼?他本質是為了解決單純撰寫 CSS 在遇到大型專案時可能出現語法重複、可維護性與可讀性不佳的問題。想進一步認識 CSS 預處理器可以看 "CSS 預處理器是什麼" 這篇文章,我覺得作者寫得非常易懂。

因為我還沒真正在一個正式專案使用過 Sass/SCSS,這篇文章的主要目的是​整理 課程上的操作說明,為接下來可能用到的情況先做一個準備。

為什麼聽起來好像很複雜,還需要特別整理...?不是說 CSS 預處理會比 CSS 更簡潔、好讀嗎,這樣不是應該比較方便嗎?那是因為 Sass/SCSS 需要編譯啊,而且語法上還多了一點點不同,不常用的話如果不自己再記錄一下的話超容易忘記的。

啊提到編譯,那又是個啥?

呃...這個問題的出發點出主要是我們在撰寫 Sass/SCSS 後沒有辦法馬上套用在 HTML 元素上,因為咱們的瀏覽器認不出他是誰啊!必須透過編譯 (compile) 轉成 plain CSS,瀏覽器才看得懂,這種感覺就像是女朋友卸妝前和卸妝後的差別,然後你就是瀏覽器



Sass/SCSS 實作

事不宜遲,先來安裝 Sass 編譯器吧!打開終端機輸入下面指令:

// 安裝 Sass 套件
​npm install sass

// 看看你安裝的位置以及版本,確認是否安裝成功
​npx which sass
npx sass --version

// 查看套件說明書
npx sass --help​

然後請打開你的 VS code,建立下圖的資料夾環境來做測試。

raw-image

先在 "main.scss" 中輸入下面指令模擬正要用作樣式處理的情境:

// main.scss
$bg_color : #b3d9ff;
$font_color : black;
body{
background-color:$bg_color;
color: $font_color;
}

接著在終端機中在輸入下列指令:

​cd test/src
npx sass main.scss output.css

你會發現多跑出了兩個檔案,其中 "output.css" 就是已經編譯過的檔案,當你打開它會發現你剛剛在 "main.scss" 寫的樣式已經被轉成很熟悉的 CSS 樣式了:

// output.css​
body {
  background-color: #b3d9ff;
  color: black;
}
可以看到多出兩個檔案啦

可以看到多出兩個檔案啦

自動追蹤編譯單一 Sass 檔案

上面這個是 "手動" 編譯一個 sass 檔案,如果我想要自動化呢?想要每次 .scss 檔案一有更動就自動編譯呢?沒關係,為了滿足人類的惰性,可以在終端機輸入這一行:

npx sass --watch main.scss:output.css 

接著我們試著更動一下 main.scss:

// 把 #b3d9ff 改成 #b3dd2d
$bg_color : #b3dd2d;

你會發現 output.css 中的樣式也跟著換過去了:

raw-image

追蹤編譯整個資料夾下的 Sass 檔案

假設我們有很多不同的 .scss 檔案要追蹤編譯呢?很顯然上面的做法就不是和我們了,但所幸開發者也早就想到這樣的情形,早早為大家準備了解方。

在這之前,先建立一個 "scss_dir" 資料夾,然後把 main.scss 移進去。

raw-image

然後一樣打開終端機,輸入這一行指令:

npx sass --watch scss_dir:css_dir

會發現專案下多出了一個存放編譯過後檔案的資料夾 "css_dir" 啦!

raw-image



使用 Webpack 管理、編譯

為什麼要用 Webpack?因為當專案內容日漸龐大時,Webpack 可以更快速地幫助我們做編譯,然後打包成一包完整的檔案方便上線。

from: https://webpack.js.org/

from: https://webpack.js.org/

只要是談到 Webpack 的文章,多半都會有上面這張圖 XD 但這裡也只是紀錄如何用 Webpack 幫忙編譯 Sass,不是 Webpack 介紹,想知道的話推薦看 :

  1. Webpack教學 (一) :什麼是Webpack? 能吃嗎?
  2. Webpack 是什麼?模組打包工具的用途及基本 Webpack 教學

專案初始化

要使用 Webpack 記得要先裝 Node.js 喔!想知道怎麼裝的話看這裡

裝好之後我們先來做專案初始化和安裝需要的套件吧!我們會需要安裝:

  • webpack
  • webpack-cli
  • css-loader
  • sass-loader
  • mini-css-extract-plugin

webpack 和 webpack-cli 負責打包,css-loader 和 sass-loader 負責編譯,mini-css-extract-plugin 負責把編譯後的 CSS 檔案抽出來。

// 初始化專案
npm init -y

// 安裝上列套件
​npm install webpack webpack-cli mini-css-extract-plugin css-loader sass-loader

這時看一下專案內容,會有npm init -y已經建立好的資料夾和檔案:

  • node_modules
  • package-lock.json
  • package.json

然後接著我們要自己建立一下專案的其他架構:

  • src:放編譯前的原始碼。
  • dist:放 webpack 編譯打包後的檔案。
raw-image

Webpack 設定

打開 webpack.config.js,來寫 webpack 的設定檔囉 !需要注意的重點有幾個:

  • entry:指的是 webpack 的進入點,我們會用 "main.js" 作為進入點。
  • output:打包後輸出的檔案。

如果你有仔細看前面的Webpack教學 (一) :什麼是Webpack? 能吃嗎?這篇文章,會發現他的設定檔比起下面設定檔 (from: ALPHA camp) 少了 module 後面整段的設定,因為他的範例只是為了打包一個 JS 檔案而已。而 ALPHA camp 裡添加這段設定是指示所有以 ".scss" 為附檔名的檔案都會用 mini-css-extract-plugin、css-loader 及 sass-loader 來編譯。

// webpack.config.js
const path = require('path')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
module.exports = {
  entry: './src/main.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'bundle.js'
  },
  module: {
    rules: [
      {
        test: /\.scss$/,
        use: [
          MiniCssExtractPlugin.loader,
          'css-loader',
          'sass-loader'
        ]
      }
    ]
  },
  plugins: [new MiniCssExtractPlugin()]
}

package.json 設定

接這來到 package.json 檔案中,找到 script 部分加入這段:

"build": "webpack --mode production"
raw-image

其他設定

接著來建立要嘗試 Sass/SCSS 的檔案內容。

index.html:

<h1>Hello, Webpack Sass</h1>

main.scss:

$bg_color : #b3d9ff;
$font_color : black;

body {
    background-color: $bg_color;

    h1 {
        color: $font_color
    }
}

main.js:

import './scss/main.scss'
console.log('JS loaded!')

接著我們在終端機輸入npm run build,會看到 dist 資料夾已經存放好編譯且打包好的檔案。

raw-image

這時我們回到 index.html 引入打包後的兩個檔案:

<head>
    <!-- ... -->
    <link rel="stylesheet" href="/dist/main.css">
</head>
<body>
    <!-- ... -->
    <script src="/dist/bundle.js"></script>
</body>

然後打開預覽,就可以看到套用了樣式的 HTML 架構囉!

raw-image



Sass/SCSS 語法

關於語法,強力建議先去看Learn Sass In 20 Minutes,會清晰很多。

而且影片一開始介紹了一個 VS code 的套件 - Live Sass Compiler,可以直接點下面操作欄的 "Watch Sass" 直接幫忙編譯成 CSS 檔案,超方便!

raw-image

在介紹語法前,我們先準備一組 HTML 架構:

<header>
        <h1>Hello, world!</h1>
        <button>Click!</button>
</header>
<div>
        <button>Submit</button>
        <p>Hello, Taiwan</p>
</div>

變數 (Variables)

變數的存在讓我們可以把很多元素都會用到的樣式統一儲存起來,這樣當專案龐大時我們不用針對一個個元素去修改 CSS 樣式,只要修改變數的部分就可以讓所有引用該變數的元素都套用這個樣式。而在 Sass/SCSS 中宣告變數是以 "$" 開頭。

$bgColor: lightblue;

header{
    background-color: $bgColor;
}

函式 (Mixins)

如果說變數是儲存單一樣式,那函式就是儲存一組樣式。舉例來說,我們很常同時使用display: flex, align-items: center, justify-content: center這樣一組樣式,那我們可以先把它儲存成函式,然後再來引用。

// 用 @mixin 宣告函式​
@mixin flexSet{
    display: flex;
    align-items: center;
    justify-content: center;
}

// 在選擇器中用 @include 引入
​header{
    background-color: $bgColor;
    @include flexSet()
}
raw-image

另外,函式也支援參數的引入,比如說我今天要讓flex-direction透過參數來設定要 row 還是 column,我們可以把剛剛的 code 改成:

@mixin flexSet($direction){
    display: flex;
    align-items: center;
    justify-content: center;
// add this​
    flex-direction: $direction;
}

header{
    background-color: $bgColor;
    @include flexSet(column);
}
raw-image

巢狀 (Nesting)

往常我們在撰寫 CSS 時,假設我們要對 header 中的 h1 做樣式設定,在不給予 id 或 class 的情況下我們會這樣寫:

header h1{
color: white;
}

但在 Sass/SCSS 中,我們可以這樣寫:

header{
    background-color: $bgColor;
    @include flexSet(column);
// add this​
    h1{
        color: white;
    }
}

這樣的巢狀結構可以避免我們一直撰寫重複的開頭,也更讓人清楚上下元素的關聯性。

往更深入講,如果想使用偽元素呢?比如今天想要讓 header 裡的 button 在 hover 時背景變成紅色,一樣可以直接用巢狀結構撰寫:

header{
    background-color: $bgColor;
    @include flexSet(column);
    h1{
        color: white;
    }
    button{
        &:hover{
        background-color: red;
        }
    }
}

繼承 (Extend)

打個比方,今天 div 跟 header 的樣式幾乎一樣,只差在背景色的呈現,難道我們也要一一撰寫 div 的樣式嗎?

不用!Sass/SCSS 的繼承讓你直接把 header 的樣式引到 div 中:

div{
// 繼承 header 樣式​
    @extend header;
// 更改背景色​
    background-color: yellow;
}
raw-image



參考資料

  1. ALPHA camp 課程
  2. 問過一百次的問題之 Sass 和 SCSS 的差別
  3. Webpack教學 (一) :什麼是Webpack? 能吃嗎?
  4. Webpack 是什麼?模組打包工具的用途及基本 Webpack 教學
  5. SCSS基本使用教學:變數、巢狀、函式、繼承寫法
  6. Learn Sass In 20 Minutes | Sass Crash Course


18會員
37內容數
這個專題用來存放我在學習網頁開發時的心得及知識。
留言0
查看全部
發表第一個留言支持創作者!
Jeremy Ho的沙龍 的其他內容
因為被 position 打敗,就要在 position 這裡站起來!
因為被 position 打敗,就要在 position 這裡站起來!
你可能也想看
Google News 追蹤
Thumbnail
這個秋,Chill 嗨嗨!穿搭美美去賞楓,裝備款款去露營⋯⋯你的秋天怎麼過?秋日 To Do List 等你分享! 秋季全站徵文,我們準備了五個創作主題,參賽還有機會獲得「火烤兩用鍋」,一起來看看如何參加吧~
Thumbnail
美國總統大選只剩下三天, 我們觀察一整週民調與金融市場的變化(包含賭局), 到本週五下午3:00前為止, 誰是美國總統幾乎大概可以猜到60-70%的機率, 本篇文章就是以大選結局為主軸來討論近期甚至到未來四年美股可能的改變
Thumbnail
Faker昨天真的太扯了,中國主播王多多點評的話更是精妙,分享給各位 王多多的點評 「Faker是我們的處境,他是LPL永遠繞不開的一個人和話題,所以我們特別渴望在決賽跟他相遇,去直面我們的處境。 我們曾經稱他為最高的山,最長的河,以為山海就是盡頭,可是Faker用他28歲的年齡...
Thumbnail
本文將介紹如何使用 CSS Media Queries 來創建適應不同裝置的網頁,在現今多裝置的網頁設計中,可以透過 CSS Media Queries 來讓我們根據不同的裝置特性,如螢幕尺寸、解析度等,來應用不同的樣式規則。
Thumbnail
本文將介紹 CSS 的四個基本概念:margin(外邊距)、padding(內邊距)、border(邊框)和 box-sizing(盒模型),接下來將透過實際的程式碼範例來展示這些概念如何運作。
Thumbnail
本文將介紹 CSS 中的position屬性,position是用於控制網頁元素在頁面上的排列,接下來將逐一介紹position屬性的五種不同值:static, relative, absolute, fixed, 和 sticky,以及它們如何影響元素的排列。
Thumbnail
本文將介紹 CSS Flexbox,CSS Flexbox 是網頁設計的佈局工具,Flexbox 能使元素的排列和對齊變得更加靈活和直觀,從而大大簡化了響應式網頁設計的過程,通過了解 Flexbox 的概念和屬性,你將能夠利用 Flexbox 創建靈活且響應性強的網頁佈局。
Thumbnail
在網頁中,每個按鈕、文字或圖片等都是通過 CSS 來設定它們的樣子,要做到這點,我們就需要用到 CSS 選擇器。本文會從最簡單的選擇器開始講起,讓你了解如何使用 CSS 選擇器。
Thumbnail
box-sizing 是 CSS 屬性的一種,它使我們可以改變盒模型的計算方式。
Thumbnail
相信大家對於 sticky 這個效果不陌生,網頁上方的導覽列、文章側邊的相關閱讀等,諸多網頁都能看見它的身影,不過這篇不是 sticky 的使用教學,而是我自己的踩雷紀錄😅💣
Thumbnail
自學程式的過程中,你總是把transform、transition,甚至是translate搞混嗎!為了分辨「轉變」的三個關係字,並理解到底什麼時候要用哪個屬性才正確,這篇筆記誕生了!
Thumbnail
這是一篇關於 CSS 動畫屬性的學習筆記,如果你剛好也在學習的話,歡迎進來看看!
Thumbnail
CSS提供許多選擇器類型,當使用不同的選擇器時,套用樣式的優先權也會不同。 A.元素內的(行內)樣式>頁面內的(崁入)樣式>外部載入(串連) 元素內的(行內)樣式 例子: 頁面內的樣式(崁入樣式) 例子: 外部載入(串連) 例子: B.後設定>前設定 最後設定的樣式將蓋過之前設定的樣式 例子:
Thumbnail
這個秋,Chill 嗨嗨!穿搭美美去賞楓,裝備款款去露營⋯⋯你的秋天怎麼過?秋日 To Do List 等你分享! 秋季全站徵文,我們準備了五個創作主題,參賽還有機會獲得「火烤兩用鍋」,一起來看看如何參加吧~
Thumbnail
美國總統大選只剩下三天, 我們觀察一整週民調與金融市場的變化(包含賭局), 到本週五下午3:00前為止, 誰是美國總統幾乎大概可以猜到60-70%的機率, 本篇文章就是以大選結局為主軸來討論近期甚至到未來四年美股可能的改變
Thumbnail
Faker昨天真的太扯了,中國主播王多多點評的話更是精妙,分享給各位 王多多的點評 「Faker是我們的處境,他是LPL永遠繞不開的一個人和話題,所以我們特別渴望在決賽跟他相遇,去直面我們的處境。 我們曾經稱他為最高的山,最長的河,以為山海就是盡頭,可是Faker用他28歲的年齡...
Thumbnail
本文將介紹如何使用 CSS Media Queries 來創建適應不同裝置的網頁,在現今多裝置的網頁設計中,可以透過 CSS Media Queries 來讓我們根據不同的裝置特性,如螢幕尺寸、解析度等,來應用不同的樣式規則。
Thumbnail
本文將介紹 CSS 的四個基本概念:margin(外邊距)、padding(內邊距)、border(邊框)和 box-sizing(盒模型),接下來將透過實際的程式碼範例來展示這些概念如何運作。
Thumbnail
本文將介紹 CSS 中的position屬性,position是用於控制網頁元素在頁面上的排列,接下來將逐一介紹position屬性的五種不同值:static, relative, absolute, fixed, 和 sticky,以及它們如何影響元素的排列。
Thumbnail
本文將介紹 CSS Flexbox,CSS Flexbox 是網頁設計的佈局工具,Flexbox 能使元素的排列和對齊變得更加靈活和直觀,從而大大簡化了響應式網頁設計的過程,通過了解 Flexbox 的概念和屬性,你將能夠利用 Flexbox 創建靈活且響應性強的網頁佈局。
Thumbnail
在網頁中,每個按鈕、文字或圖片等都是通過 CSS 來設定它們的樣子,要做到這點,我們就需要用到 CSS 選擇器。本文會從最簡單的選擇器開始講起,讓你了解如何使用 CSS 選擇器。
Thumbnail
box-sizing 是 CSS 屬性的一種,它使我們可以改變盒模型的計算方式。
Thumbnail
相信大家對於 sticky 這個效果不陌生,網頁上方的導覽列、文章側邊的相關閱讀等,諸多網頁都能看見它的身影,不過這篇不是 sticky 的使用教學,而是我自己的踩雷紀錄😅💣
Thumbnail
自學程式的過程中,你總是把transform、transition,甚至是translate搞混嗎!為了分辨「轉變」的三個關係字,並理解到底什麼時候要用哪個屬性才正確,這篇筆記誕生了!
Thumbnail
這是一篇關於 CSS 動畫屬性的學習筆記,如果你剛好也在學習的話,歡迎進來看看!
Thumbnail
CSS提供許多選擇器類型,當使用不同的選擇器時,套用樣式的優先權也會不同。 A.元素內的(行內)樣式>頁面內的(崁入)樣式>外部載入(串連) 元素內的(行內)樣式 例子: 頁面內的樣式(崁入樣式) 例子: 外部載入(串連) 例子: B.後設定>前設定 最後設定的樣式將蓋過之前設定的樣式 例子: