BEM
BEM là gì?
BEM là chữ viết tắt của Block, Element, Modifier. BEM được tạo ra bởi Yandex.
Cũng giống như FLOCSS, BEM là một tiêu chuẩn quy ước cách đặt tên class trong CSS, có thể kết hợp với FLOCSS để làm cho quy ước đặt tên class thêm phong phú và chặt chẽ.
Các kỹ thuật đặt tên được đề cập trong bài viết này không phải là kỹ thuật BEM gốc mà là phiên bản đã được cải tiến bởi Nicolas Gallagher, gọi là MindBEMding. Dù ký hiệu thực tế được sử dụng là khác nhau nhưng về cơ bản chúng đều dựa trên nguyên tắc BEM.
Vì sao sử dụng BEM?
- BEM giúp cho các thành viên trong team làm việc dễ dàng và thống nhất với nhau hơn.
- BEM cung cấp cho CSS của bạn một cấu trúc vững chắc, đơn giản, dễ hiểu và dễ sửa chữa hơn.
- BEM giúp code CSS ít bị ảnh hưởng hoặc trùng lặp lẫn nhau.
- BEM là giải pháp giúp giảm thời gian suy nghĩ tên class.
Cách sử dụng BEM
Tên class theo quy tắc BEM bao gồm ba loại:
Block__Element--Modifier
- Block: là một thành phần của trang web, một thực thể độc lập có ý nghĩa riêng.
- Element: là phần tử con của phần tử Block.
- Modifier: là hình thức, hành vi hoặc trạng thái của Block/Element.
Dưới đây là một ví dụ tổng quan.
Bạn sẽ thấy có 2 khối giống nhau nên ta coi đây là một component (tên lớp phải bắt đầu bằng tiền tố c-).
- Tên class cho block là
c-imgtxt - Trong block
c-imgtxtcó 2 phần tử con (element), tên class của chúng phải kế thừa tên lớp từc-imgtxttheo cấu trúc:c-imgtxt__***, ví dụ:c-imgtxt__imagevàc-imgtxt__text - Block 2 chỉ khác block 1 ở màu chữ, để chỉnh sửa định dạng màu chữ cho block 2, ta thêm class mới ngang hàng với class
c-imgtxt__textnơi cần sửa đổi.
Có thể hiểu định dạng của lớp mới này ghi đè lên định dạng của lớpc-imgtxt__textcũ, tên lớp này mới phải kế thừa tên lớpc-imgtxt__texttheo cấu trúc:c-imgtxt__text--***, ví dụ:c-imgtxt__text--red
Block
Ví dụ trên có một block có viền bao quanh, bên trái là img, bên phải là text
=> Coi nó là một block và đặt tên class cho nó, ví dụ: .c-sample (tiền tố c- của FLOCSS).
| Quy tắc đặt tên cho Block | HTML | CSS |
|---|---|---|
Tên block có thể bao gồm các chữ cái Latinh, chữ số và dấu gạch ngang. Để tạo một lớp CSS, có thể thêm tiền tố FLOCSS(c-, p-...) vào tên class:.block, .c-block | Bất kỳ nút DOM nào cũng có thể là một block.<div class="block">...</div> | - Chỉ sử dụng bộ chọn tên class - Không dùng tên thẻ hoặc id - Không phụ thuộc vào các block/element khác trên cùng trang .block { color: #042; } |
Element
Trong block c-sample có 2 thành phần con là img và text, nên tên lớp của chúng phải kế thừa tên lớp c-sample theo cấu trúc: c-sample__***, ví dụ: c-sample__img, c-sample__text
| Quy tắc đặt tên cho Element | HTML | CSS |
|---|---|---|
Tên element có thể bao gồm các chữ cái Latin, chữ số, dấu gạch ngang và dấu gạch dưới. Lớp CSS được hình thành dưới dạng tên block cộng với hai dấu gạch dưới cộng với tên element: .block__elem | Bất kỳ nút DOM nào trong một block đều có thể là một element<div class="block">...<span class="block__elem"></span></div> | - Chỉ sử dụng bộ chọn tên class - Không dùng tên thẻ hoặc id - Không phụ thuộc vào các block/element khác trên cùng trang Good .block__elem {color: #042;}Bad .block .block__elem { color: #042; } div.block__elem { color: #042; } |
Modifier
Tiêu đề DummyDummy chỉ có chút khác biệt về màu sắc của đường viền bên trái.
Vì vậy, chúng ta sẽ tạo các class anh em của class gốc c-title1 để sửa đổi màu của đường viền bên trái.
Class anh em sẽ được tạo ra theo cấu trúc c-title1--***, ví dụ: c-title1--yellow, c-title1--red.
Style của những class mới này sẽ được ghi đè lên style cũ.
| Quy tắc đặt tên cho Modifier | HTML | CSS |
|---|---|---|
| Modifier có thể bao gồm các chữ cái Latin, chữ số, dấu gạch ngang và dấu gạch dưới. Lớp CSS được hình thành dưới dạng tên của block/element cộng với hai dấu gạch ngang: .block--mod, .block__elem--mod.Dấu cách trong các từ bổ nghĩa phức tạp được thay thế bằng dấu gạch ngang: .block--color-black, .block__elem--color-red. | Modifier là một tên class bổ sung mà bạn thêm vào nút DOM block/element. Chỉ thêm các lớp modifier vào các block/element cần sửa đổi và giữ nguyên lớp ban đầu: Good <div class="block block--mod">…</div><div class="block block--size-big block--shadow-yes">...</div>Bad <div class="block--mod">…</div> | Modifier cho block:.block--hidden { }Để thay đổi các element dựa trên modifier cấp block: .block--mod .block__elem { }Modifier cho element: .block__elem--mod { } |
Những sai lầm cần tránh khi sử dụng BEM
- Khi viết BEM, gặp trường hợp sau phần element có thêm các element “cháu, chắt, chút, chít”… bạn cứ viết element như bình thường (
block__child2) chứ không viết nối tiếp nhiều dấu gạch dưới (block__element__child1__child2), điều này sẽ khiến tên class quá dài. - Để viết modifier cho đúng thì bắt buộc phải có phần element hoặc block trước đó.
- Sử dụng BEM vào một block quá lớn, có nhiều thẻ con là không nên. Bởi BEM là để tạo ra các khối module vừa, nhỏ và có thể tái sử dụng. Khi gặp các trường hợp này, bạn nên tách thành các block nhỏ hơn.
- Vì mục đích bảo trì, sửa chữa trang web và tiết kiệm thời gian, không nên đặt class cho tất cả các thẻ mà không cần style.