<style>
.title{
font-size:20px;
font-weight:bold;
color:#283593;
}
</style>
# BEM 學習
###### tags: `OKR` `自主學習` `SCSS/BEM`
###### 2020/07/11(Update)
## 7/11學習內容
學習來源:
[BEM官方文件](http://getbem.com/introduction/)
[youtube資源學習](https://www.youtube.com/watch?v=er1JEDuPbZQ&t=308s)
---
<div class="title">什麼是BEM?</div>
1. 以Block結構來命名Html Class Name。
2. 全名叫Block/Element/Modifier。
3. Block:一個區塊包覆相同的內容結構,例如下方卡片範例,卡片最外面的一層就叫Block。
4. Element:卡片裡面的各項內容抽出來就叫element,例如圖片img/標題title/描述desc/按鈕button。
5. Modifier:代表修飾符號名稱,比較簡單的說法是這個Element狀態事件發生或是形體上的改變、不同的類型,例如我們專案上常會寫到按鈕被active或是卡片有分light/dark類型,如下範例。
<center class="half">
<img src="https://i.imgur.com/6XuX1B0.png" />
<p>BEM命名範例</p>
</center>
```sass
<div class="card card--light"></div>
<div class="card card--dark"></div>
```
<div style="text-align:center">形體上的改變、不同的類型</div>
<br>
<div class="title">用BEM的好處是什麼</div>
1. 雖然感覺Class命名變長,但整體結構能讓沒寫這專案的人都能快速理解。
2. 命名很長的問題,透過搭配撰寫SCSS就可解決。
3. 很多命名會重覆的區塊就可以模組化共用使用。
4. 變的更好維護。
<div class="title">BEM基本寫法</div>
如果是Element:blockname__elementname ( 二個下底線 _ _ )
```htmlmixed
<div class="card__title"></div>
```
如果是Modifier:blockname__elementname--ModifierStatus ( 二個連字符 - - )
過往都是直接寫active/hidden/success 等寫法,BEM寫法換成以下方式
```htmlmixed
<div class="card__button card__button--active"></div>
<div class="card__button card__button--is-active"></div>
<div class="card__button card__button--is-hidden"></div>
```
<div class="title">使用SCSS撰寫BEM樣式</div>
當Html架構寫好後,開始撰寫BEM樣式,結合SCSS寫法
```sass
/* SCSS結構 */
.card{
&__title{.....}
&__button{
//......
&--active{.......}
}
}
```
```sass
/* CSS編譯結果 */
.card__title{....}
.card__button{.....}
.card__button--active{.....}
```
Classname也可以加上 ' - ',使用前缀
```htmlmixed
<form class="site-search site-search--full">
<input type="text" class="site-search__field">
<input type="Submit" value ="Search" class="site-search__button">
</form>
```
```sass
/* SCSS結構 */
.site-search{}
.site-search__field{}
.site-search__button{}
.site-search--full{}
```
<div class="title">BEM最好的寫法</div>
在撰寫時,除了更換命名的方式,但撰寫SCSS結構時也需要一併思考,整個結構先以一個Block命名開始,其它必須統一一致,例如:
```htmlmixed
<button class="button">基本按鈕</button>
<button class="button button--state-success">成功按鈕</button>
<button class="button button--state-danger">警示按鈕</button>
```
我們應該怎麼寫SCSS?
```sass
/* 1.首先先寫好預設按鈕的結構 */
.button{
border-radius: 3px;
padding: 7px 12px;
border: 1px solid #D5D5D5;
font-size:16px;
text-align:center;
/* 2.在把Modifier所需狀態使用的SCSS寫出來 */
&--state-success{
color: #FFF;
background: #569E3D linear-gradient(#79D858, #569E3D) repeat-x;
border-color: #4A993E;
}
&--state-danger{
color: #900;
}
}
```
<div class="title">撰寫時遇到的問題紀錄</div>
#### 問題一
實際撰寫時,當使用Modifiter時--active,雖然搭配SCSS天衣無縫,不需要寫太長的名稱,但若是使用在JS上時,你必須要將完整的Classname寫上去,雖然一樣名稱太長,但一樣若能讓每個人容易理解之優點來說還是大過於此缺點,也或許是自己可能還沒尋找到最佳方法。
```javascript
$('.card__button').addClass('.card__button--active');
```
#### 問題二
實際撰寫時一定要整個結構一致,否則會吃不到子層的樣式,遇到問題是希望在同層加上同一結構但不同類型的Class狀態。
例如這張卡片需要dark(暗色系)或是light(亮色系)。下方範例會發什麼事情,.card.light的樣式會吃不到底下的.card__item樣式,意思是CSS沒辦法吃到(.card.light .card__item),猜測應該是撰寫BEM規則時,SCSS在編譯時可能沒法整併。
```sass
/* 1.light or dark 非BEM寫法 */
<div class="card light">
<div class="card__item"></div>
<div class="card__item"></div>
<div class="card__item"></div>
</div>
<div class="card dark">
<div class="card__item"></div>
<div class="card__item"></div>
<div class="card__item"></div>
</div>
```
```sass
/* 2.當撰寫時,SCSS to css 吃不到__item */
.card{
&.light{
&__item{
........
}
}
&.dark{
&__item{
........
}
}
}
```
改寫方法:
```sass
/* 1.加上modifier類型 */
<div class="card card--light">
<div class="card__item"></div>
<div class="card__item"></div>
<div class="card__item"></div>
</div>
<div class="card card--dark">
<div class="card__item"></div>
<div class="card__item"></div>
<div class="card__item"></div>
</div>
```
```sass
/* 2.先寫好card基本結構,並在給予light/dark增加顏色樣式等內容 */
.card{
//3.這裡寫card基本結構
.....
//4.再來針對light/dark寫樣式
&--light{
color:#ffffff;
}
&--dark{
color:#000000;
}
.__item{
.....
}
}
```
這樣每個class在同一個card Block底下結構均都不受影響,不需要為了某個結構在重覆改寫。
#### 問題三
在查看BEM官方文件[CSS層疊繼承所帶來的問題](https://www.phase2technology.com/blog/used-and-abused-css),發現了原來自己撰寫時也可能會犯下的不好習慣,有些地方過度濫用CSS層疊繼承,覆蓋原有編寫的樣式問題。下方的圖片反而造成樣式不斷被重覆改寫,程式碼太多/浪費等問題。
<center class="half">
<img src="https://i.imgur.com/3IVwTCs.png" />
<p>CSS層疊繼承</p>
</center>
改寫方法:
如同模組化的概念,樣式應該要更加彈性,應該是要可獨立/可重用/不受任何父層影響/更好維護。