1) BEM là gì?
BEM là viết tắt của Block, Element, và Modifier. Đây là phương pháp do Yandex đề xuất để giúp CSS có cấu trúc nhất quán, tránh xung đột, và dễ tái sử dụng.
- Block: Thành phần độc lập, có thể tồn tại riêng (ví dụ:
.button,.card,.menu). - Element: Phần con của block, không thể tồn tại độc lập (ví dụ:
.button__icon,.card__title). - Modifier: Biến thể hoặc trạng thái của block hoặc element (ví dụ:
.button--primary,.card--featured).
2) Cú pháp chuẩn của BEM
block-name
block-name__element-name
block-name--modifier-name
Trong đó:
- Dấu gạch dưới kép (
__) nối giữa block và element. - Dấu gạch ngang kép (
--) nối giữa tên và modifier.
3) Ví dụ cơ bản
<button class="button button--primary">
<span class="button__icon">🔥</span>
<span class="button__label">Đăng ký</span>
</button>
.button {
display: inline-flex;
align-items: center;
gap: 0.5rem;
padding: 0.75rem 1.25rem;
border-radius: 0.5rem;
background-color: #ddd;
color: #000;
}
.button__icon {
width: 1.25rem;
height: 1.25rem;
}
.button--primary {
background-color: #007bff;
color: #fff;
}
Giải thích:
.button là block chính.
.button__icon và .button__label là phần tử bên trong.
.button--primary là biến thể (modifier) thể hiện phiên bản màu xanh.
4) Ưu điểm của BEM
- Tránh trùng lặp: Class có tên rõ ràng theo component.
- Dễ mở rộng: Thêm modifier mà không phá vỡ cấu trúc CSS cũ.
- Không phụ thuộc cấu trúc DOM: Chỉ cần đúng class là style áp dụng — dù HTML thay đổi nhẹ.
- Phù hợp với framework: BEM tương thích tốt với Tailwind, SASS, SCSS, hay CSS Modules.
- Đọc code dễ hiểu: Nhìn tên class là biết vị trí và vai trò trong component.
5) Ví dụ phức tạp hơn: Card component
<article class="card card--featured">
<img class="card__image" src="/img/post.jpg" alt="Ảnh minh họa">
<div class="card__content">
<h2 class="card__title">CSS BEM là gì?</h2>
<p class="card__text">Tìm hiểu quy tắc đặt tên rõ ràng và nhất quán trong CSS.</p>
</div>
</article>
.card {
background: #fff;
border-radius: 12px;
overflow: hidden;
box-shadow: 0 2px 6px rgba(0,0,0,0.1);
}
.card__image {
display: block;
width: 100%;
height: auto;
}
.card__content {
padding: 1rem;
}
.card__title {
font-size: 1.25rem;
margin-bottom: 0.5rem;
}
.card__text {
color: #555;
}
.card--featured {
border: 2px solid #007bff;
}
6) Khi nào nên dùng BEM?
- Khi dự án có nhiều component UI tái sử dụng.
- Khi làm việc nhóm, cần thống nhất quy tắc CSS.
- Khi dùng CSS thuần hoặc SCSS mà không có CSS-in-JS.
- Khi muốn dễ refactor và tránh xung đột style.
7) Những lỗi thường gặp
- Dùng BEM nửa vời (vừa có
.header__logovừa.logođộc lập). - Dùng BEM nhưng vẫn lồng selector quá sâu trong CSS (phá mục tiêu độc lập của BEM).
- Dùng
__hoặc--sai vị trí, hoặc đặt tên chung chung (.box__item--1không rõ nghĩa).
8) Mẹo đặt tên dễ đọc
- Dùng tiếng Anh đơn giản, có nghĩa, tránh viết tắt khó hiểu (
.nav__itemtốt hơn.nv__it). - Dùng kebab-case (
block-name__element-name--modifier-name). - Không cần phản ánh cấu trúc DOM — chỉ phản ánh quan hệ logic giữa các phần.
Kết luận
BEM giúp CSS trở nên có tổ chức, dễ bảo trì và mở rộng, đặc biệt khi dự án lớn hoặc làm việc nhóm. Khi bạn quen với quy tắc block__element--modifier, bạn sẽ thấy code CSS trở nên nhất quán và ít lỗi hơn — và đó là bước đầu tiên để viết CSS chuyên nghiệp.
Bình luận