CSS 預處理器 SCSS

SCSS 使用和 CSS 一樣的區塊({})與定義結尾(;)語法,是基於 CSS 語法的超集(superset)。如果你已經有一些 CSS 語法的基礎,學習 SCSS 會很容易, 雖然它有一些類似程式語言的語法,但都相當簡單易用,並沒有太複雜的語法。為了與之前的 SASS 語法作區分,檔案的副檔名使用.scss。(舊語法則使用.sass)

簡單用幾個範例示範 CSS 預處理器的幾個常用的特性:變數(Variables)、函式(Functions)、嵌套(Nesting)、混入(Mixins)、共用(Extends)。

CSS 預處理器

CSS 預處理器可以說是 CSS 語法的擴充。為了彌補 CSS 在大型專案維護性的不足,CSS 預處理器中新增了變數、混入、繼承、嵌套等寫法, 讓開發者可以更有結構地撰寫簡潔、清晰且好維護的 CSS 程式碼。

現今較為主流的 CSS 預處理器有三種,分別是 Sass/SCSS、Less、Stylus,其中的 Sass/SCSS 是目前最多人使用也相對較成熟的選擇。

基本語法實作

建立編譯環境

SCSS 本身需要使用命令列工具進行編譯。這些工具可以與現有的程式開發或網頁編輯程式作搭配使用,支援很多也很廣泛。 也有網頁版的線上編輯工具如 SassMeisterCodePen,或是專用圖形化介面應用程式。 要在自己的電腦上使用 SCSS 通常需要使用兩種工具,一個是用於編譯 SCSS 檔案為 CSS 檔案的"編譯工具"。 另一個則是對 SCSS 程式碼的"語法檢查工具"。

變數與運算

可以用錢號($)來定義變數,用冒號(:)來指定變數的值,這與 CSS 定義屬性值很相似。在檔案中的其他地方就使用這些變數值。

變數的命名通常使用在 CSS 中常見的屬性名稱寫法,也就是用連接號(-)與全小寫英文,例如$second-color,變數在編譯後並不會出現在最後輸出的 CSS 檔案中。

此外,變數也可以指定給其他變數使用,變數的值也可以是一個字串值,不過解譯時有特別的語法。

//scss
$color-white: #fff;
$color-pink: #ee11ab;
$title-font: normal 24px/1.5 'Open Sans', sans-serif;

$primary-color: $color-pink;

a {
  background-color: $color-white;
  color: $color-pink;
}

變數可以再進行作加減乘除餘(+-*/%)運算,最特別的是字串與顏色色碼也可以進行運算。
$_num: 5px;

.container {
  color: $color-pink / 2;
  margin: $_num * 2 $_num;
}

嵌套(Nesting)

嵌套語法可以使用明確的階層定義,例如像下面的選單或清單項目的風格定義:
SCSS CSS
// scss
ul {
  list-style: none;

  li {
    display: inline-block;
    padding: 15px;

    a {
      color: #444;
      font-size: 16px;
      text-decoration: none;
    }
  }
}
        
ul {
  list-style: none;
}

ul li {
  display: inline-block;
  padding: 15px;
}

ul li a {
  color: #444;
  font-size: 16px;
  text-decoration: none;
}        

匯入(Import)

匯入其他的 SCSS 檔案,最後編譯時會一併包含進來編譯。要被匯入的通常檔案名稱前會加下底線(_)作區分,這樣編譯工具在編譯時會略過這些檔案, 而只會去編譯那些沒下底線(_)的檔案,例如_reset.scss。

例如base.scss中要匯入_reset.scss,base.scss的檔案內容會如下,要注意的是只需要寫@import 'reset',不用加副檔名或下底線(_), 編譯程式會自動尋找對應的檔案:

@import 'reset';

body {
  background-color: #efefef;
  font: 100% Helvetica, sans-serif;
}

混合(Mixin)

混合(Mixin)有點像是個函式或是一群值的組合,也可以輸入一個值然後套用這個值的整串結果。經常用於需要相符不同瀏覽器品牌的 CSS3 宣告上, 來解決供應商前綴字的問題。例如以下的範例:
@mixin border-radius($radius) {
  -webkit-border-radius: $radius;
  -moz-border-radius: $radius;
  -ms-border-radius: $radius;
  border-radius: $radius;
}

.box {
  @include border-radius(10px);
}
要記住的是@minix標記需要對應到@include標記,上面的@include border-radius(10px)可以像變數一樣,加在 scss 檔案中的任一個定義中。

這個mixin中的定義傳入值,是可以加上預設值的,例如以下的範例:

@mixin label($text: 'Code', $background: $yellow, $color: rgba(black, 0.5)) {
  position: relative;
  &:before {
    background: $background;
    color: $color;
    content: $text;
    display: inline-block;
    font-size: 0.6rem;
  }
}

擴充/繼承(Extend)

擴充(Extend)是可以擴充原有的 CSS 類別定義,你可以再加上不同的定義或覆蓋原有的定義,例如下面的範例:

轉成 CSS 會像右面這樣,你可能會注意到.message仍然被保留著:

.message {
  border: 1px solid #ccc;
  padding: 10px;
  color: #333;
}

.success {
  @extend .message;
  border-color: green;
}

.error {
  @extend .message;
  border-color: red;
}
.message,
.success,
.error {
  border: 1px solid #ccc;
  padding: 10px;
  color: #333;
}

.success {
  border-color: green;
}

.error {
  border-color: red;
}

函式(Functions)

SCSS 中也有@function可以定義自訂的函式,也有一些簡單的程式語法,例如@return、@if、@for、@each等流程控制的特性,以及簡單的運算能力。
@function calculate-width($col-span) {
  @return 100% / $col-span;
}

.span-two {
  width: calculate-width(2); // spans 2 columns, width = 50%
}

.span-three {
  width: calculate-width(3); // spans 3 columns, width = 33.3%
}
SCSS 中也內建了許多工具函式,詳見內建函式的清單。 常用的例如按比例加亮顏色的 lighten 與按比例加深顏色的 darken,裡面有關於顏色、透明度、字串、數字的函式很多。以下為範例:
$awesome-blue: #2196f3;

a {
  background-color: $awesome-blue;
  padding: 10px 15px;
}

a:hover {
  background-color: darken($awesome-blue, 10%);
}

註解(Comment)

用類似程式碼寫法的兩條斜線(//)就可以加入註解。CSS 的話是規定要用/*...*/的註解記號,相較之下會簡單些。

參考資料