# 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/)