BEM 規範思維 – 讓 CSS 更利於開發與維護 (一)
BEM 是什麼?
BEM 是一種前端項目開發的方法學,由 Yandex 公司提出。BEM 的名稱源於該方法學的三個组成部分英文字首,分别為 Block、Element 和 Modifier。這三個部分的結合稱為 BEM 實體。
BEM 背後的思維是將用戶界面劃分為各種獨立的模塊(Block)。 即使當 UI 過於複雜時,也可以輕鬆快速地進行界面開發,並且無需複製和黏貼即可重複使用現有程式碼。
*官方網址: http://getbem.com/
為什麼要使用 BEM ?
因應當前網頁發展爆炸趨勢,前端程式碼複雜度大大提升,尤其是 JavaScript 和 CSS 的數量大幅增加,程式命名的識別度、一致性就成了首要課題,找出適合自己與團隊的程式組織方法和命名規範就變得相對重要!BEM 所提供的是一種思維方向,我們可以透過其中了解其應用邏輯,至於要如何使用、如何實現,還是根據自己的情況做調整。
BEM 內容介紹
Block
圖片來源:https://en.bem.info/methodology/key-concepts/
Block 指的是 Web 應用開發中的模組。每個 Block 在邏輯和功能上都是相互獨立。由於Block 是獨立的,可以在開發中進行複用,進而降低程式碼重複並提高開發效率,Block 可以放置在頁面上的任何位置,也可以互相嵌套。
特色:
- Block name 描述它的目的(“它是什麼?” – menu 或 button ),而不是它的狀態(“它看起來像什麼?” – red 或 big )
<!-- 正確。 `error` block 具有語意上的意義--> <div class="error"></div> <!-- 不正確。此為描述外觀 --> <div class="red-text"></div>
- Block 不能影響所在環境,這意味著我們不應該設置任何會影響到外部的 style(例如:margin)
- 我們也不應該在使用 BEM 時,使用 CSS 標籤選擇器和 ID 選擇器
以上確保了重複使用 Block 或將它們從一個地方移動到另一個地方的必要獨立性
嵌套:
- Block 和 Block 之間可以彼此嵌套
- 可以有任意級別的嵌套層次
<!-- `header` block --> <header class="header"> <!-- 嵌套 `logo` block --> <div class="logo"></div> <!-- 嵌套 `search-form` block --> <form class="search-form"></form> </header>
Element
圖片來源:https://en.bem.info/methodology/key-concepts/
Element 是 Block 中的组成成分。Element 不能脫離 Block 單獨使用。
特色:
- Element name 如同 Block name 描述的是目的而非狀態
- Element name 的完整結構是block-name__element-name。Element name 使用雙下劃線(__)與 Block name 名稱分隔。
<!-- `search-form` block --> <form class="search-form"> <!-- `input` element 位在 `search-form` block --> <input class="search-form__input"> <!-- `button` element 位在 `search-form` block --> <button class="search-form__button">Search</button> </form>
嵌套:
- Element 和 Element 之間可以彼此嵌套
- 可以有任意級別的嵌套層次
- Element 始終是Block 的一部分,而不是另一個 Element 。 這表示 Element name 無法定義層次結構,例如 block__elem1__elem2
<!-- 正確。Element name 結構符合以下模式: `block-name__element-name` --> <form class="search-form"> <div class="search-form__content"> <input class="search-form__input"> <button class="search-form__button">Search</button> </div> </form> <!-- 不正確。 Element name 結構不符合模式: `block-name__element-name` --> <form class="search-form"> <div class="search-form__content"> <input class="search-form__content__input"> <button class="search-form__content__button">Search</button> </div> </form>
- Block 在 DOM tree 中具有嵌套元素的結構:
<div class="block"> <div class="block__elem1"> <div class="block__elem2"> <div class="block__elem3"></div> </div> </div> </div>
但是,此 Block 的結構以 BEM 表示則呈現出並列的 Element 列表:
.block {} .block_elem1 {} .block_elem2 {} .block_elem3 {}
這允許我們在不更動每個單獨 Element 下改變一個 Block 的 DOM 結構。
<div class="block"> <div class="block__elem1"> <div class="block__elem2"></div> </div> <div class="block__elem3"></div> </div>
雖然 Block 的結構發生變化,但 Element name 與其規則仍然保持不變。
组成部分:
Element 始終是 Block 的一部分,我們不應該單獨使用它。
<!-- 正確。Element 都用於 the `search-form` block 內--> <!-- `search-form` block --> <form class="search-form"> <input class="search-form__input"> <button class="search-form__button">Search</button> </form> <!-- 不正確。 Elements are located outside of the context of the `search-form` block --> <!-- `search-form` block --> <form class="search-form"> </form> <input class="search-form__input"> <button class="search-form__button">Search</button>
選擇性:
Element 是選擇性的組件。 並非所有 Block 都需要有 Element。
小結
如何判斷應該是要創建一個 Block 還是一個 Element?
假如這段程式碼可能會再次使用,而且它不依賴於頁面上的其他组件,那應該創建一個 Block。
如果這段程式碼在没有 parent entity(Block)的情况下無法使用,那我們應該創建一個Element。
以上簡單介紹了 Block 和 Element 的區別與其特性,在下一篇文章將說明 Modifier 還有其他 BEM 資料介紹!
更多電商營運相關的知識,歡迎訂閱歐斯瑞電子報,以及追蹤我們的粉絲專頁!
延伸閱讀:
快速查詢CSS/HTML與各瀏覽器的支援-Can I Use
參考資料:
https://en.bem.info/methodology/
https://segmentfault.com/a/1190000012633974
我要留言