CSS 預處理器-SCSS, Sass


Posted by saffran on 2021-02-25

什麼是 CSS 預處理器?

原本的 CSS 是不具有「程式」的概念的,但我現在可以用程式的概念去寫 CSS(例如用 function、迴圈、變數來寫,可以讓開發更加順利),再用 CSS 預處理器幫我把這些新的語法轉換成 CSS 的標準語法

SCSS 簡介

style.css.map 這個檔案就是所謂的 source map,幫我把 style.css 的內容對應到 style.scss(實際在開發的檔案)

Mixins 就是 function 的感覺

也可以傳入參數

Sass 簡介

CSS 在開發上的問題

如果沒有使用像是 Sass 這樣的預處理器,CSS 在開發上會有這些問題:

  • 全域會互相干擾
  • 沒有變數(現在有 CSS Variable)
  • 沒有辦法組合

壓縮 css 檔的語法

在最後的 production 階段,如果想要壓縮 css 檔案,就在 terminal 輸入:

sass --style=compressed main.sass main.css

Sass 結構化 - 變數與巢狀

Sass 模組化 - import, extend, mixin 與 function

extend

extend 就像是大一點的變數,例如 object

style.sass:
%btn 先寫好一個 template

%btn
  padding: 1rem 2rem
  color: green
  font-size: 1rem

.btn
  &-primary
    @extend %btn
  &-secondary
    @extend %btn
  &-warning
    @extend %btn

style.css:
會用逗號的方式去幫三個 class 套用同一個 template

.btn-warning, .btn-secondary, .btn-primary {
  padding: 1rem 2rem;
  color: green;
  font-size: 1rem;
}

mixin

style.sass:

@mixin btn
  padding: 1rem 2rem
  color: green
  font-size: 1rem

.btn
  &-primary
    +btn
  &-secondary
    +btn
  &-warning
    +btn

style.css:
會分別幫三個 class 套用同一個 template(會複製貼上三次)

.btn-primary {
  padding: 1rem 2rem;
  color: green;
  font-size: 1rem;
}
.btn-secondary {
  padding: 1rem 2rem;
  color: green;
  font-size: 1rem;
}
.btn-warning {
  padding: 1rem 2rem;
  color: green;
  font-size: 1rem;
}

mixin 設定預設值

把水平置中寫死,但是因為不一定需要垂直置中,所以 top 只有先給預設值是 50%,意思就是:如果沒有傳 $top,那 $top 就會是 50%

@mixin absCenter($top: 50%)
  position: absolute
  top: $top
  left: 50%
  transform: translate(-50%, -50%)

extend 的使用時機:

當元素有共用樣式時

mixin 的兩個使用時機:

1. 當我需要帶變數進去時(就像是在寫 function 一樣)

style.sass:

$primary: orange
$secondary: grey
$warning: red

%btn
  padding: 1rem 2rem
  color: green
  font-size: 1rem

@mixin hover-btn($color)
  &:hover
    background-color: $color

.btn
  &-primary
    @extend %btn
    +hover-btn($primary)
  &-secondary
    @extend %btn
    +hover-btn($secondary)
  &-warning
    @extend %btn
    +hover-btn($warning)

style.css:

.btn-warning, .btn-secondary, .btn-primary {
  padding: 1rem 2rem;
  color: green;
  font-size: 1rem;
}

.btn-primary:hover {
  background-color: orange;
}
.btn-secondary:hover {
  background-color: grey;
}
.btn-warning:hover {
  background-color: red;
}

2. 把常用功能用 mixin 包起來(放到另一個獨立的檔案叫做 _mixins.sass)

@mixin flex-center
  display: flex
  justify-content: center
  align-items: center

function

function 跟 mixin 的差別在於:function 可以回傳數值

以下範例是 function 搭配 mixin 使用
style.sass:
可以看到
function 適合用在「當我需要在一個屬性下做運算」時,function 可以回傳我想要的值,例如這裡的 letter-spacing
mixin 適合用在「當我需要打包一組功能」時

$primary: orange
$secondary: grey
$warning: red

%btn
  padding: 1rem 2rem
  color: green
  font-size: 1rem

@function letter-spacing($font-index)
  @return $font-index/10 * 0.2rem

@mixin hover-btn($color, $font-index)
  &:hover
    background-color: $color
    letter-spacing: letter-spacing($font-index)

@mixin flex-center
  display: flex
  justify-content: center
  align-items: center

.btn
  &-primary
    @extend %btn
    +hover-btn($primary, 10)
  &-secondary
    @extend %btn
    +hover-btn($secondary, 30)
  &-warning
    @extend %btn
    +hover-btn($warning, 100)

Sass 與 CSS 渲染規則

Sass 自動化 - condition 與 loop

詳細可參考 Flow Control Rules

第一種迴圈 @each

@each 適合搭配我們自己定義好的變數(list, map)來使用

Sass 的陣列(list)

在 Sass 也有類似 JS 的 array 的資料格式,在 Sass 叫做 list,語法是這樣:

$direction-types: center, start, end

@each 搭配 list 的應用

style.sass:
$type 就是 $direction-types 裡面的每一個 type

$direction-types: center, start, end

@each $type in $direction-types
  .flex-#{$type}
    display: flex
    justify-content: $type
    align-items: center

style.css:
在這裡用 list 是不適合的,因為這樣 justify-content 後面就只會有 start, end,但應該要是 flex-start, flex-end
因此,要改為使用 map(後面的範例)

.flex-center {
  display: flex;
  justify-content: center;
  align-items: center;
}

.flex-start {
  display: flex;
  justify-content: start;
  align-items: center;
}

.flex-end {
  display: flex;
  justify-content: end;
  align-items: center;
}

Sass 的物件(map)

在 Sass 也有類似 JS 的 object 的資料格式,在 Sass 叫做 map,語法是這樣:

$direction-types: (center: center, start: flex-start, end: flex-end)

@each 搭配 map 的應用

style.sass:
$type 就是 $direction-types 裡面的每一個 key
$value 就是 key 裡面的每一個 value

$direction-types: (center: center, start: flex-start, end: flex-end)

@each $type, $value in $direction-types
  .flex-#{$type}
    display: flex
    justify-content: $value
    align-items: center

style.css:

.flex-center {
  display: flex;
  justify-content: center;
  align-items: center;
}

.flex-start {
  display: flex;
  justify-content: flex-start;
  align-items: center;
}

.flex-end {
  display: flex;
  justify-content: flex-end;
  align-items: center;
}

第二種迴圈 @for

@for 適合用在當我想要預先開好一系列的字級、位置
style.sass:

@for $i from 0 through 5    
  .h#{5 - $i + 1}
    font-size: 1 + 0.2rem * $i

style.css:

.h6 {
  font-size: 1rem;
}

.h5 {
  font-size: 1.2rem;
}

.h4 {
  font-size: 1.4rem;
}

.h3 {
  font-size: 1.6rem;
}

.h2 {
  font-size: 1.8rem;
}

.h1 {
  font-size: 2rem;
}

判斷式 @if...@else

style.sass:

注意!在 Sass 裡面要做判斷是用「兩個等號 ==」,不是「三個等號 ===

@for $i from 0 through 5    
  .h#{5 - $i + 1}
    @if $i % 2 == 0
      font-size: 1 + 0.2rem * $i
    @else
      font-size: 1 + 0.3rem * $i

Sass 檔案分類

第一個部分:variables, mixins

把 zeplin 右邊的顏色、字體整理成 variables

變數命名方式分為兩類:

  • 功能類,像是 $color-primary
  • 數值類,像是 $red-01

把常用的功能、樣式整理成 mixins

第二個部分:components

把一些「跨頁的元件」整理成 components
像是按鈕、標題

第三個部分:layouts

把每頁共同的區塊,整理到 layouts 裡面
像是:navbar, footer

集合上面所有部分:pages

最後,再用一個 pages 把剩下的版面排好後,把每個部分都 import 進來,就會是一包完整的 sass 檔案


#SCSS #SASS







Related Posts

【JS上課筆記】非同步(asynchronous)VS. 同步(synchronous)

【JS上課筆記】非同步(asynchronous)VS. 同步(synchronous)

[Structure] Int32 VS Int64

[Structure] Int32 VS Int64

計數排序(Counting Sort)、基數排序(Radix Sort)

計數排序(Counting Sort)、基數排序(Radix Sort)


Comments