Skip to content

SCSS 語法構成:與 CSS 的關係、縮排語法對照

SCSS 語法構成與縮排語法對照

SCSS 最重要的一件事是:它是 CSS 的超集合。任何一份合法的 CSS,把副檔名改成 .scss 就是一份合法的 SCSS,編譯出來的結果幾乎原封不動。所有 Sass 的能力都是在這個基礎上「加上去」的。

一份 SCSS 檔裡有什麼

scss
@use "sass:color"; // ① at-rule

$brand: #2965f1; // ② 變數

@mixin center { // ③ 混入定義
  display: flex;
  justify-content: center;
}

.card { // ④ 規則
  @include center; // ⑤ 混入呼叫
  color: $brand;

  &:hover { // ⑥ 巢狀
    color: color.scale($brand, $lightness: -20%);
  }
}
元素是 CSS 就有的嗎說明
規則(選取器 + 宣告區塊)CSS 語法構成 完全相同
變數 $brand編譯後被換成值,見 變數
at-rule @use@mixin部分@media 是 CSS 的;@mixin 是 Sass 的
巢狀與 &Sass 先有編譯時攤平,見 巢狀規則
// 註解不會出現在產出,見 註解

Sass 專屬的 at-rule

CSS 原本就有 @media@supports@keyframes@font-face,這些在 SCSS 裡照寫不誤,會原樣輸出。Sass 另外加了一批 只活在編譯期 的 at-rule:

用途at-rule
模組@use@forward
重複使用@mixin@include@function@return@extend
流程控制@if@else@each@for@while
其他@at-root@debug@warn@error@content

判斷方式很單純:產出的 CSS 裡看得到的就是 CSS 的,看不到的就是 Sass 的。

與縮排語法的對照

同一段樣式的兩種寫法:

scss
// SCSS(.scss)
@mixin theme($color) {
  color: $color;
}

.card {
  @include theme(#2965f1);

  .title {
    font-weight: 700;
  }
}
sass
// 縮排語法(.sass)
@mixin theme($color)
  color: $color

.card
  +theme(#2965f1)

  .title
    font-weight: 700
項目SCSS縮排語法
區塊大括號縮排
宣告結尾分號換行
呼叫混入@include name+name
與 CSS 的關係超集合,可直接貼 CSS不相容,要改寫
副檔名.scss.sass

兩者可以互轉

Dart Sass 的 sass-convert 已移除,但兩種語法可以在同一個專案共存,@use 一個 .sass 檔到 .scss 檔裡是合法的。實務上沒必要混用。

從 CSS 遷移過來

改副檔名就能動,但有兩個地方值得先確認:

一、除法符號。 舊寫法的 / 在 Dart Sass 已被棄用,font: 12px/1.5 這種 CSS 簡寫要留意,數值計算請改用 math.div()

二、原生 CSS 變數與插值。 自訂屬性 的值不會被 Sass 處理,想把 Sass 變數塞進去要用 插值

scss
$brand: #2965f1;

:root {
  --brand: #{$brand}; // 要插值,直接寫 $brand 會原樣輸出
}

別在 SCSS 裡混用原生巢狀

原生 CSS 巢狀要靠瀏覽器支援,Sass 巢狀在編譯時就攤平了。同一份檔案裡兩種混用,維護時很難分辨哪一段是編譯期處理的。既然用了 Sass,巢狀就交給 Sass。

常見問題

現有的 CSS 可以直接改成 SCSS 嗎?

可以。SCSS 是 CSS 的超集合,把副檔名從 .css 改成 .scss 就能編譯,產出的結果與原本幾乎一樣。唯一要留意的是原生 CSS 的 var()calc() 與 Sass 的插值混用時的寫法。

該選 SCSS 還是縮排語法?

選 SCSS。它與 CSS 長得一樣,貼上一段從別處抄來的 CSS 不用改寫,團隊成員也不需要額外學習,社群資源與工具支援都以它為主。縮排語法只在少數偏好極簡風格的專案裡出現。

SCSS 裡的 at-rule 有哪些?

除了 CSS 本身的 @media@supports@keyframes 之外,Sass 另外提供 @use@forward@mixin@include@function@return@extend@if@each@for@while@at-root@debug@warn@error 等,這些都會在編譯階段被處理掉。

SCSS 檔裡可以寫原生 CSS 巢狀嗎?

可以,但沒有必要。Sass 的巢狀在編譯時就會被攤平成一般選取器,相容性更好;原生巢狀則要瀏覽器支援。同一份檔案裡兩種混用只會讓人搞不清楚哪一段是編譯期處理的。

延伸閱讀