淺談 CSS 設計模式-SMACSS 篇
前言
CSS 設計模式是一個觀念、規範以及心法,最主要就是要替我們提高開發與維護的效率。
SMACSS
SMACSS 其實是一個縮寫,我們可以透過 官方網站 了解到其實全名是「Scalable and Modular Architecture for CSS」,中文意思是可以擴展且模組化的 CSS 架構。
而 SMACSS 其中主要的核心架構是以下
- Base
- Layout
- Module
- State
- Theme
Base (基礎)
Base 是屬於所有網站的基礎架構,概念與 CSS Reset 概念雷同,因此 CSS Reset 就是屬於 SMACSS 中的 Base 的一種。
因此假使來講今天有一段 CSS 像以下這樣
1 | .header a { |
在上述中我們可以看到 a
這個超連結標籤都有幾個個共通的 CSS 屬性也就是 color: red;
以及 display: inline-block;
,因此我們可以基於 SMACSS Base 核心觀念將這兩個 CSS 設置成網站預設樣式。
因此我們可以改寫成這樣
1 | a { |
我們可以看到 a
連結的基礎樣式就可以變成通用樣式且可以減少 CSS 重複撰寫,通過這種方式我們可以滿足網頁上八成的樣式,那至於剩下的兩成呢?此時就會使用覆蓋的概念
1 | a { |
所以 Base 的核心觀念在於「在一開始就賦予整個網頁的預設初始樣式,進而減少重複的預設樣式」,因此若某一天需要修改預設樣式時,就只需要調整 Base 即可。
在 SCSS 中通常我們會將 Base 的相關設定獨立出來成一個檔案叫做 _base.scss,並在 CSS Reset 之後,因此在引入時的結構就會像這樣
1 | @import '_variable.scss'; |
當然你也可以將 Base 寫在 reset,可是以我自己的習慣來講,我會將 reset 獨立,主要是增加 CSS 彈性,舉例來說,若我將 Base 寫在 reset,所以這個 reset 支援 A 網站,但當轉移網站時,他就不支援 B 網站,因此通常會比較傾向 CSS Reset 獨立成一隻會較好。
前面講了很多 Base 基本觀念,但沒有實際應用其實很難了解一個所以然,因此這邊可以參考 Yahoo! 開發的 Pure.css Base
其實 Pure.css 的 Base 非常的小,而他使用的 CSS Reset 是 normalize 來調整成自己的 Base。
Layout (佈局)
Layout 主要用於共用的頁面,舉例來講 header 以及 footer,因此通常我們會將 Layout 獨立出一隻來寫 header、footer 以及 nav 等。
1 | @import '_variable.scss'; |
使用 Layout 的觀念可以幫助我們若要調整 header 或 footer 時,就可以非常直覺的找 _layout.scss
調整。
當然 Layout 不只有用於 header 或 footer,假使若有三四個頁面底下都是使用相同的樣式
1 | .indexCard { |
因此這些樣式其實都非常雷同,在維護上就會非常麻煩,當然這邊也有人可能會這樣子寫
1 | .indexCard, .orderCard, .carCard { |
當然這種做法並沒有不好,只是每一次新增你就必須在寫一次,此外也有可能會有人這樣寫,直接統一一種 className
1 | .carCard { |
這種做法當然沒有不好,但若拿語意來看就會相當奇怪,我這個頁面明明是清單頁面,為什麼 className 會是購物車?又或者是我明明這裡是首頁,為什麼會是購物車?因此在語義上就非常不好,因此在 SMACSS 中的 Layout 觀念中就會叫你「統一一個抽象名稱」,因此名字就會是一個 l-
,l
代表著 Layout,並搭配 Card
1 | .l-card { |
因此通常 Layout 會有一個前綴詞 l-
,透過這種抽象的概念,就可以減少自己在那邊思考 className 的問題,通常只要這個區塊重複性會高達五六成左右,就會將它歸納為 Layout,所以最後總結一下 Layout 的重點在於「抽象語義化命名,抽象出共用樣式」,透過 Layout 你就比較不用在那邊想語義衝突以及語義太詭異的問題。
Module (模組)
在許多框架中都有使用到這個模組化的觀念,舉凡 Boostrap 或是前面所講的 Pure.css 都有使用到這個觀念,因此 SMACSS 中也有這個模組化觀念。
舉例來講,當我們有三個按鈕樣式是這樣
1 | .btn-blue { |
此時我們可以發現這些按鈕除了 background-color
之外,其他都是相同的,那麼我們就可以使用 SMACSS 的 Module 觀念,如果你沒有使用 Module 觀念的話,假使三個按鈕要調整大小或 color
時,你就必須調整三次,因此若套用 SMACSS 的 Module 觀念之後我們可以調整成這樣
1 | .btn { |
在這邊 Module 的核心觀念在於「抽出主要的基礎樣式」,因此我們可以將主要的樣式給抽取出來獨立,當下次若要使用時,我們只需要 btn btn-blue
,下次若新增別的 class 的時候,就可以減少再次重複撰寫,更不用說若要調整按鈕的時候,就可以一次調整,你可以發現 Module 的概念與 Base 很雷同,但 Base 主要是用於「初始化 HTML 標籤的預設樣式」,所以與 Module 是不同的觀念。
最後這邊要注意一件事情,盡可能 CSS 不要針對 HTML 標籤給予樣式,這樣子會大大減少 CSS 的彈性
1 | .table h2 { |
在 SMACSS 中他會希望你改寫成這樣
1 | .table-title { |
這樣子才能夠大大增加 CSS 的活用性。
State (狀態)
SMACSS 中的 State 就相對比較簡單一點,舉例來講按鈕可能會有狀態的切換或是一些訊息提示
1 | .is-active { |
通常狀態都會使用 .is-
當作前綴詞,Status 與 Module 是存在一個非常模糊的關係,他們彼此都是修改現有元素的外觀,但在 SMACSS 中對於 Status 的重點在於
- 狀態的樣式可以用於任意 Layout 或是 Module
- 狀態是依賴於 JavaScript 才加入的
此外這邊還有一件很特別的事情 Status 是允許你使用 !important
,通常來講你是不會在一個 CSS 上面放入兩個 Status 必定是只有一個 .is-error
或 is-success
,所以除非你的系統非常複雜,否則 !important
基本上用不到。
Theme (主題)
Theme 這個風格使用的機會非常非常的低,就連 SMACSS 官方都說
Theme Rules aren’t as often used
因此這部分若有興趣可以自己看一下官方文件說明就好了。