---
# System prepended metadata

title: SCSS設計模式

---

# SCSS設計模式
## BEM(Block Element Modifier)
### 概述
以**功能導向**(Function-Oriented Programming, FOP)的概念進行開發的class命名模式
### 規則
* `[Block]__[Element]--[Modifier]`
    * **區塊 Block**
        * 可獨立存在的對象
        * 名稱應清楚表達其用途，使其具備可讀性及**唯一性**
    * **元素 Element**
        * 可視為區塊元件底下的子元件
        * Element使用雙底線`__`來連結及辨識
    * **修飾符 Modifier**
        * 主要用來表述Block、Element的**行為**或**樣式**
        * Modifier使用雙橫線`--`來連結及辨識
* 應避免過度模組化、Sass過多嵌套(一般來說三層較佳)
* HTML標籤名稱太長連帶影響DOM元素的取得，降低JavsScript可讀性

### 優點
1. 結構清晰
    * 一般寫法：較難在只瀏覽class名稱的情況下直接了解彼此的關係

        ```html
        <ul class="menu">
          <li class="item active">首頁</li>
          <li class="item">分類</li>
          <li class="item">購物車</li>
        </ul>
        ```
    * 以BEM規則進行改寫：可迅速得知`menu`屬於區塊、`menu__item`為`menu`底下的元素，而`menu__item--active`為`menu__item`的其中一種狀態
        ```html
        <ul class="menu">
          <li class="menu__item menu__item--active">首頁</li>
          <li class="menu__item">分類</li>
          <li class="menu__item">購物車</li>
        </ul>
        ```
2. 具備重用性，減少重複撰寫相同的css

### Sass支援BEM設計模式
* 簡化前

    ```css
    .menu {}
    .menu__item {}
    .menu__item--active {}
    ```
* 簡化後：可讀性及管理效率提升

    ```sass
    .menu {
      &__item {}
      &__item {
        &--active {}
        }
      }
    ```
    
## OOCSS(Object Oriented CSS)
### 概述
* 依循**物件導向**(Object-Oriented Programming, OOP)的方式撰寫，追求CSS物件化、模組化
* 應撰寫樣式文件，以理解每個class的用途
### 規則
1. Separate structure and skin：**分離結構與樣式**
    * 當按鈕有不同的樣式需求時，若未分離結構與樣式，將重複撰寫相同程式碼
		    
      ```css
      .btn-primay {
        display: inline-block;
        padding: 5px 10px;
        color: black;
        border: 1px solid black;
        background-color: #CCCCCC;
      }

      .btn-active {
        display: inline-block;
        padding: 5px 10px;
        color: green;
        border: 1px solid green;
        background-color: #F6FAF3;
      }
      ```
    * 利用分離結構與樣式的規範進行改寫

      ```css
      .btn {
        display: inline-block;
        padding: 5px 10px;
      }

      .btn-primay {
        color: black;
        border: 1px solid black;
        background-color: #CCCCCC;
      }

      .btn-active {
        color: green;
        border: 1px solid green;
        background-color: #F6FAF3;
      }
      ```
    * 不同的按鈕套用各自所需的樣式

      ```html
      <button class="btn btn-primary">Primary</button>
      <button class="btn btn-active">Active</button>
      ```
2. Separate container and content：**分離容器與內容**
    * 在一般撰寫方式中，按鈕與`.content`綁死，無法在其他地方使用
      ```css
      .content {
        display: flex;
        flex-direction: column;
        width: 100%;
      }

      .content button {
        display: inline-block;
        padding: 5px 10px;
      }
      ```
    * 當容器與內容分離後，`.btn`便可被任意使用
		    
      ```css
      .content {
        display: flex;
        flex-direction: column;
        width: 100%;
      }

      .btn {
        display: inline-block;
        padding: 5px 10px;
      }
      ```
    * 故應盡量避免使用後代選擇器`.content button`，父子元素不互相依賴

### 優點
* OOCSS規範使得網頁樣式可透過各種「組合」來創造，更便於管理及維護
* 例如Bootstrap便是以此設計模式進行命名

## 參考文章
* [BEM — Block Element Modifier](https://getbem.com)
* [Object-Oriented CSS](http://oocss.org)
* [Sass/SCSS 預處理器 - OOCSS、SMACSS、BEM 模組化方法論](https://awdr74100.github.io/2020-06-19-scss-oocss-smacss-bem/)