Skip to content

Sass 是什麼?CSS 預處理器入門與它解決的五個問題

Sass 是什麼?CSS 預處理器入門

Sass(Syntactically Awesome Style Sheets)是一種用來撰寫網頁樣式的語言,寫完之後會被 編譯 成一般的 CSS 供瀏覽器使用,所以它被歸類為 CSS 預處理器(CSS Preprocessor)。

重點在 預處理 這三個字:瀏覽器從頭到尾都只認得 CSS,Sass 提供的變數、迴圈、函式全都在編譯階段就被算完、換成單純的 CSS,執行時不留下任何痕跡。它不是新的樣式技術,是寫樣式時多墊的一層工具。

它解決什麼問題

原生 CSS 是一份宣告清單,沒有變數以外的抽象能力。專案一大就會遇到這五件事:

痛點Sass 的做法
同一個主色散落在幾十處變數 抽成一個名字,改一處就好
選取器層層重複前綴巢狀規則 依 DOM 結構縮排書寫
一段樣式在多個元件重複貼@mixin 定義一次、到處 @include
樣式全擠在一個大檔@use 拆成多檔,編譯後合成一份
十二欄柵格要手寫十二條規則@for 迴圈自動產生

用一段最短的例子看差別:

scss
$brand: #2965f1;

.card {
  border: 1px solid $brand;

  &__title {
    color: $brand;
  }
}

編譯出來就是普通得不能再普通的 CSS:

css
.card {
  border: 1px solid #2965f1;
}
.card__title {
  color: #2965f1;
}

SCSS 與縮排語法

Sass 有兩種寫法,指的是同一個語言:

寫法副檔名特徵
SCSS.scss用大括號與分號,是 CSS 的超集合
縮排語法.sass用縮排取代大括號,不寫分號
scss
/* SCSS */
.card {
  color: #333;
}
sass
/* 縮排語法 */
.card
  color: #333

SCSS 是 CSS 的超集合,意思是任何一份合法的 CSS 直接改副檔名就是合法的 SCSS,遷移舊專案幾乎零成本。這也是它成為主流的原因。

本系列一律使用 SCSS

往後所有範例都是 .scss 寫法。兩者的差別只在標點,觀念完全共用,細節見 語法構成

三個實作版本

「Sass」是語言規格,實作它的程式有三個,現在只剩一個活著:

實作狀態說明
Dart Sass現行標準官方主推,新功能只會出現在這裡。npm 上的 sass 套件就是它
LibSass已停止維護(2020)C++ 實作,node-sass 包的就是它,不支援模組系統
Ruby Sass已停止維護(2019)最初的實作

看到 node-sass 就該換掉

node-sass 依賴的 LibSass 早已停更,不支援 @usesass:math 等現代寫法,安裝時還常因為原生模組編譯失敗。改裝 sass 即可,詳見 安裝與編譯

那原生 CSS 補上的功能呢

這幾年 CSS 本身也在補課,兩項功能與 Sass 高度重疊:

  • 自訂屬性:CSS 有自己的變數了,而且比 Sass 變數更強,會繼承、能在執行時用 JavaScript 改。
  • 原生巢狀:現代瀏覽器已支援 & 與巢狀規則。

所以今天用不用 Sass,判斷標準變成剩下那些原生 CSS 做不到的事:

  • 條件判斷與迴圈(@if@each)。
  • 自訂函式(@function)與內建的色彩、數學運算。
  • 把樣式拆成幾十個檔案,編譯後合成一份 CSS(模組系統)。

實務上兩者是搭配而不是取代:編譯期算得完的交給 Sass,執行期才知道的值交給 CSS 自訂屬性,這個分工的細節見 搭配 CSS 自訂屬性

常見問題

Sass 和 SCSS 差在哪?

兩者是同一個語言的兩種寫法。SCSS 用大括號與分號,副檔名 .scss,語法是 CSS 的超集合,任何合法的 CSS 都是合法的 SCSS;縮排語法用縮排取代大括號,副檔名 .sass。現在絕大多數專案用的都是 SCSS。

有了 CSS 巢狀與自訂屬性,還需要 Sass 嗎?

原生 CSS 已經補上巢狀與 自訂屬性,這兩項確實不再是使用 Sass 的理由。但迴圈、條件判斷、自訂函式、把樣式拆成多檔再合併成一個檔案這幾件事,原生 CSS 仍然做不到,這是 Sass 至今還被廣泛使用的原因。

該裝哪一個 Sass?

Dart Sass,也就是 npm 上的 sass 套件。LibSass 與 Ruby Sass 都已經停止維護,新功能不會再加,舊專案應該遷移過來。

瀏覽器看得懂 Sass 嗎?

看不懂。瀏覽器只認得 CSS,.scss 檔必須先經過編譯產生 .css 檔,網頁載入的永遠是編譯後的那份 CSS。

延伸閱讀