BEM CSS là gì? Hướng dẫn toàn tập cho người mới bắt đầu

Bạn đã bao giờ cảm thấy “ngộp thở” trong một file CSS dài hàng nghìn dòng chưa? Sử dụng phương pháp BEM CSS chính là tấm bản đồ giúp bạn thoát khỏi mê cung đó. Đây là một quy ước đặt tên đơn giản nhưng cực kỳ mạnh mẽ, giúp code của bạn trở nên gọn gàng và dễ bảo trì hơn bao giờ hết. Hãy cùng WiWeb tìm hiểu toàn bộ về BEM và cách áp dụng nó vào dự án của bạn ngay hôm nay.

Giới thiệu BEM

Nếu bạn từng làm việc với một dự án CSS lớn, chắc hẳn bạn đã gặp phải những vấn đề quen thuộc: class đặt tên chồng chéo, độ ưu tiên (specificity) gây xung đột, và việc chỉnh sửa một thành phần lại vô tình làm hỏng một thành phần khác. CSS, dù mạnh mẽ, nhưng rất dễ trở nên hỗn loạn nếu thiếu một quy tắc rõ ràng.

BEM CSS là gì?

BEM là viết tắt của Block, Element, Modifier. Đây không phải là một framework hay thư viện, mà là một phương pháp đặt tên (CSS naming convention) cho các class CSS. Mục tiêu của BEM là giúp các nhà phát triển tạo ra những đoạn code có cấu trúc rõ ràng, dễ đọc, và có thể tái sử dụng. Nó chia giao diện người dùng thành các khối độc lập, giúp việc phát triển và bảo trì trở nên đơn giản hơn rất nhiều.

Tại sao nên sử dụng BEM? Vấn đề CSS truyền thống gặp phải

CSS truyền thống thường dựa vào việc lồng các selector vào nhau (nesting), ví dụ .article .title a. Cách viết này tạo ra các vấn đề lớn:

  • Xung đột Specificity: Selector càng dài và phức tạp, độ ưu tiên càng cao. Điều này dẫn đến cuộc chiến “!important” để ghi đè style, khiến code rất khó quản lý.
  • Khó bảo trì: Khi nhìn vào một class CSS như .title, bạn không thể biết nó thuộc về thành phần nào và việc thay đổi nó có ảnh hưởng đến đâu.
  • Khó tái sử dụng: Các style bị gắn chặt vào một cấu trúc HTML cụ thể. Bạn không thể dễ dàng lấy một nút bấm từ chân trang để dùng trong phần đầu trang mà không viết lại CSS.

BEM methodology giải quyết triệt để những vấn đề này bằng cách tạo ra các class có tên gọi tường minh, độc lập và không phụ thuộc vào cấu trúc HTML. Bạn sẽ luôn biết chính xác mỗi class phục vụ mục đích gì.

Giới thiệu BEM: Giải pháp cho CSS
Giới thiệu BEM: Giải pháp cho CSS “rối rắm”

Phân tích chi tiết 3 thành phần cốt lõi của BEM

Để hiểu rõ quy tắc BEM, chúng ta cần nắm vững ba khái niệm nền tảng của nó. Hãy tưởng tượng bạn đang lắp ráp một mô hình Lego. BEM cũng hoạt động tương tự như vậy.

Block – Các khối giao diện độc lập, có thể tái sử dụng

Block là một thành phần giao diện độc lập và có ý nghĩa riêng. Nó giống như một mảnh Lego hoàn chỉnh. Block có thể được đặt ở bất kỳ đâu trên trang và có thể lồng vào nhau. Tên Block phải mô tả mục đích của nó.

  • Ví dụ: header, menu, search-form, card, button.
  • Quy tắc: Tên Block thường là một danh từ, ngắn gọn và dễ hiểu.
  • Trong CSS: .header, .card, .search-form.

Element – Các thành phần con phụ thuộc vào Block

Element là một phần của Block và không thể tồn tại độc lập bên ngoài Block đó. Nó giống như một chi tiết nhỏ trên mảnh Lego, ví dụ như bánh xe của một chiếc ô tô. Element chỉ có ý nghĩa trong ngữ cảnh của Block chứa nó.

  • Ví dụ: Một menu (Block) có thể có các item (Element). Một card (Block) có thể có titleimage (Elements).
  • Quy tắc: Tên Element được nối với tên Block bằng hai dấu gạch dưới (__).
  • Trong CSS: .menu__item, .card__title, .card__image.

Modifier – Các biến thể về trạng thái hoặc giao diện

Modifier được dùng để định nghĩa các biến thể về giao diện, trạng thái hoặc hành vi của một Block hoặc một Element. Nó giống như việc bạn có các mảnh Lego cùng hình dạng nhưng khác màu sắc.

  • Ví dụ: Một button (Block) có thể có trạng thái disabled. Một menu__item (Element) có thể đang active.
  • Quy tắc: Tên Modifier được nối với tên Block hoặc Element bằng hai dấu gạch nối (--).
  • Trong CSS: .button--disabled, .menu__item--active, .card--large.
Phân tích chi tiết 3 thành phần cốt lõi của BEM
Phân tích chi tiết 3 thành phần cốt lõi của BEM

Quy tắc đặt tên và Cú pháp BEM chuẩn

Việc tuân thủ đúng cú pháp là chìa khóa để khai thác sức mạnh của BEM. Các quy tắc này rất đơn giản và nhất quán, giúp cho code của bạn luôn dễ đọc và dễ đoán.

Cú pháp block__element

Cú pháp này dùng để chỉ một thành phần con của một khối. Luôn nhớ rằng Element là một phần không thể tách rời của Block.

  • Đúng: .search-form__input, .search-form__button
  • Sai: .search-form__input__icon (Không được tạo element của element).

Cú phápblock–modifier và block__element–modifier

Cú pháp này được sử dụng để áp dụng một biến thể cho Block hoặc Element. Bạn nên giữ lại class gốc và thêm class có modifier vào.

  • Sửa đổi Block: <div class="card card--featured">...</div>
  • Sửa đổi Element: <button class="button button--primary">...</button>

Bằng cách này, class .card sẽ chứa các style cơ bản, còn .card--featured chỉ chứa những thay đổi cụ thể. Cách làm này giúp maintainable CSS (CSS dễ bảo trì) hơn.

Các lỗi thường gặp và cách tránh

Khi mới bắt đầu, bạn có thể mắc một vài lỗi nhỏ. Dưới đây là những lỗi phổ biến và cách để tránh chúng:

  • Lồng các selector BEM: Không bao giờ viết .card .card__title. Hãy viết thẳng .card__title. BEM được thiết kế để giữ cho specificity ở mức thấp.
  • Tạo element của element: Cú pháp block__elem1__elem2 là sai. Nếu cần lồng sâu hơn, hãy cân nhắc tạo một Block mới.
  • Sử dụng tên thẻ HTML trong selector: Tránh viết div.card hay .card a. Hãy tạo một class BEM mới, ví dụ .card__link.
  • Sửa đổi Element mà không có Block: Modifier của Element nên đi kèm với class gốc của Element đó. Ví dụ <a class="menu__link menu__link--active"> thay vì chỉ <a class="menu__link--active">.
Quy tắc đặt tên và Cú pháp BEM chuẩn
Quy tắc đặt tên và Cú pháp BEM chuẩn

Hướng dẫn áp dụng BEM qua các ví dụ thực tế

Lý thuyết sẽ trở nên dễ hiểu hơn rất nhiều khi được áp dụng vào thực tế. Hãy cùng WiWeb xem qua một vài ví dụ (BEM by example) về cách xây dựng các component phổ biến nhé.

Ví dụ 1: Xây dựng component Card

Một component card thường có ảnh, tiêu đề, mô tả và một nút bấm.

HTML:

<div class="card">
  <img class="card__image" src="image.jpg" alt="Product Image">
  <h3 class="card__title">Tên sản phẩm</h3>
  <p class="card__description">Đây là mô tả ngắn về sản phẩm.</p>
  <a href="#" class="card__button button--primary">Xem chi tiết</a>
</div>

<!-- Card với Modifier -->
<div class="card card--dark">
  ...
</div>

CSS:

.card {
  border: 1px solid #ccc;
  border-radius: 8px;
  padding: 16px;
}

.card__image {
  width: 100%;
  height: auto;
}

.card__title {
  font-size: 20px;
  margin: 10px 0;
}

.card--dark {
  background-color: #333;
  color: white;
}

Ví dụ 2: Tạo một thanh điều hướng (Navigation Menu)

Thanh điều hướng là một ví dụ tuyệt vời về Block và Element.

HTML:

<nav class="nav">
  <ul class="nav__list">
    <li class="nav__item">
      <a href="#" class="nav__link">Trang chủ</a>
    </li>
    <li class="nav__item nav__item--active">
      <a href="#" class="nav__link">Sản phẩm</a>
    </li>
    <li class="nav__item">
      <a href="#" class="nav__link">Liên hệ</a>
    </li>
  </ul>
</nav>

CSS:

.nav__list {
  display: flex;
  list-style: none;
  padding: 0;
}

.nav__item {
  margin-right: 20px;
}

.nav__item--active .nav__link {
  font-weight: bold;
  color: #007bff;
}

Ví dụ 3: Thiết kế Form liên hệ

Form là tập hợp của nhiều thành phần nhỏ, rất phù hợp với cấu trúc BEM.

HTML:

<form class="contact-form">
  <div class="contact-form__group">
    <label for="name" class="contact-form__label">Họ tên</label>
    <input type="text" id="name" class="contact-form__input">
  </div>
  <div class="contact-form__group">
    <label for="email" class="contact-form__label">Email</label>
    <input type="email" id="email" class="contact-form__input">
  </div>
  <button type="submit" class="contact-form__submit">Gửi</button>
</form>

CSS:

.contact-form__group {
  margin-bottom: 15px;
}

.contact-form__label {
  display: block;
  margin-bottom: 5px;
}

.contact-form__input {
  width: 100%;
  padding: 8px;
  border: 1px solid #ccc;
}
Hướng dẫn áp dụng BEM qua các ví dụ thực tế
Hướng dẫn áp dụng BEM qua các ví dụ thực tế

Câu hỏi thường gặp FAQ

Khi đã nắm vững những kiến thức cơ bản, bạn có thể sẽ có một vài câu hỏi nâng cao hơn. WiWeb sẽ giải đáp giúp bạn ngay sau đây.

SASS/SCSS là công cụ tuyệt vời để viết hướng dẫn BEM một cách gọn gàng. Bạn có thể sử dụng tính năng lồng (nesting) và ký tự & để tự động tạo ra các tên class BEM chuẩn.

Ví dụ viết lại CSS cho component card:


.card {
  border: 1px solid #ccc;
  border-radius: 8px;
  padding: 16px;

  &__image {
    width: 100%;
    height: auto;
  }

  &__title {
    font-size: 20px;
    margin: 10px 0;
  }

  &--dark {
    background-color: #333;
    color: white;
  }
}

Cách viết này trực quan và dễ quản lý hơn rất nhiều đúng không nào?

Cả BEM và SMACSS đều là những phương pháp tổ chức CSS, nhưng chúng có cách tiếp cận khác nhau.

  • BEM tập trung vào quy ước đặt tên cho các component. Nó rất nghiêm ngặt và tường minh, cực kỳ phù hợp cho các dự án xây dựng dựa trên component.
  • SMACSS (Scalable and Modular Architecture for CSS) tập trung vào phân loại các quy tắc CSS thành các nhóm: Base, Layout, Module, State, Theme. Nó mang tính kiến trúc tổng thể hơn.

Khi nào dùng cái nào? Bạn hoàn toàn có thể kết hợp cả hai. Dùng SMACSS để cấu trúc tổng thể cho file CSS và dùng BEM để đặt tên cho các Module. Đây là một sự kết hợp rất mạnh mẽ.

Câu trả lời là . Mặc dù sự trỗi dậy của các framework JavaScript như React, Vue với CSS-in-JS và Scoped CSS đã cung cấp các giải pháp khác để quản lý style, BEM vẫn cực kỳ giá trị.

  • Nó không phụ thuộc vào công nghệ, có thể áp dụng cho mọi dự án.
  • Nó là một kỹ năng nền tảng vững chắc giúp bạn viết CSS có tổ chức.
  • Trong các hệ thống lớn hoặc các đội nhóm đông người, một quy ước đặt tên chung như BEM giúp mọi người làm việc hiệu quả hơn.

Vì vậy, học và sử dụng BEM vẫn là một khoản đầu tư xứng đáng cho bất kỳ nhà phát triển front-end nào.

Câu hỏi thường gặp và kiến thức nâng cao về BEM
Câu hỏi thường gặp và kiến thức nâng cao về BEM

Lời kết

Qua hướng dẫn BEM toàn tập này, chúng ta có thể thấy việc áp dụng BEM mang lại rất nhiều lợi ích thiết thực. Nó không chỉ là một quy tắc đặt tên, mà là một tư duy về cách xây dựng giao diện một cách có hệ thống.

Những lợi ích chính bạn sẽ nhận được bao gồm:

  • Dễ bảo trì (Maintainability): Code CSS trở nên dễ đọc, dễ hiểu và dễ dàng thay đổi mà không gây ra các hiệu ứng phụ không mong muốn.
  • Tính module (Modularity): Các component hoàn toàn độc lập. Bạn có thể dễ dàng di chuyển một Block từ nơi này sang nơi khác mà không cần sửa đổi CSS.
  • Khả năng tái sử dụng (Reusability): Bạn có thể tái sử dụng các component trên khắp dự án, giúp tiết kiệm thời gian và công sức.
  • Làm việc nhóm hiệu quả: Khi cả nhóm tuân theo một quy tắc chung, việc hợp tác trở nên trôi chảy và nhất quán hơn.

Bắt đầu với BEM có thể hơi lạ lẫm, nhưng một khi đã quen, bạn sẽ thấy nó giúp công việc của mình trở nên ngăn nắp và hiệu quả hơn rất nhiều.

Bạn còn câu hỏi nào về BEM CSS không? Hãy chia sẻ thắc mắc của bạn ở phần bình luận bên dưới nhé!

Nếu bạn cần một website chuyên nghiệp được xây dựng trên nền tảng code vững chắc và dễ bảo trì, WiWeb luôn sẵn sàng tư vấn. Liên hệ với chúng tôi nhé!

5/5 - (84 Đánh giá)
Bình luận

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *