Tìm hiểu về BEM - Hiểu đúng nguyên tắc

Trở lại với series về BEM, hôm nay chúng ta sẽ cùng tìm hiểu về cách viết code cho component theo đúng nguyên tắc của BEM

Block

Thường là mô tả mục đích của nó như: menu hoặc button. Chứ không phải là trạng thái của nó red hoặc big

Block có thể được lồng trong những block khác

Ví dụ: Một block head có thể bao gồm 1 block logo, một block search, một block menu và một block auth

Một block có thể được di chuyển ở nhiều vị trí trên trang nên hãy làm sao cho nó có thể đối vị trí trên trang mà đảm bảo không ảnh hưởng đến giao diện (như vỡ layout). Vậy nghĩa là bạn không nên thiết lập position cho block.

Ví dụ: block logo và block auth có thể đổi vị trí cho nhau mà không cần sửa CSS của 2 block đó

Element

Element là 1 phần của block và nó không được sử dụng ngoài block được

Ví dụ:

Menu item không thể được sử dụng ngoài phạm vi của block menu được

<!-- Đúng. Vì các elements được đặt trong `search-form` block -->
<form class="search-form">
    <input class="search-form__input">
    <button class="search-form__button">Search</button>
</form>

<!-- Sai. Vì element `button` bị đặt ngoài `search-form` block -->
<form class="search-form">
    <input class="search-form__input">
</form>
<button class="search-form__button">Search</button>

Element thì có thể được lồng trong element khác và có thể lồng nhiều cấp. Nhưng hãy chú ý rằng một element luôn luôn phải là một phần của block, không phải là của element khác. Vậy tức là tên element không thể được viết như này block__elem1__elem2

Ví dụ:

<!-- Đúng. Vì cấu trúc tên của 1 element follow đúng pattern: `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>

<!-- Sai. Vì cấu trúc tên của 1 element không follow đúng pattern: `block-name__element-name` -->
<form class="search-form">
    <div class="search-form__content">
        <!-- Gợi ý sửa lại: `search-form__input` or `search-form__content-input` -->
        <input class="search-form__content__input">

        <!-- Gợi ý sửa lại: `search-form__button` or `search-form__content-button` -->
        <button class="search-form__content__button">Search</button>
    </div>
</form>

Element là optional (không bắt buộc phải có) trong một block

<!-- `search-form` block -->
<div class="search-form">
    <!-- `input` lúc này được mô tả như 1 block, không còn là 1 element của `search-form` block nữa -->
    <input class="input">

    <!-- `button` lúc này được mô tả như 1 block, không còn là 1 element của `search-form` block nữa -->
    <button class="button">Search</button>
</div>

Modifier

Là thực thể mà nó định nghĩa sự xuất hiện (appearance), trạng thái (state) hoặc hành vi (behavior) của một block hoặc element.

Một class modifier không bao giờ được đứng 1 mình. Tức là nó phải luôn được đi kèm với 1 class block hay element

<!-- Đúng -->
<button class="button button--small">Button</button>

<!-- Sai -->
<button class="button--small">Button</button>

Tổng kết

Việc hiểu những nguyên tắc vàng trong BEM và vận dụng nhuần nhuyễn sẽ giúp cho bạn khai thác tối đa sức mạnh mà phương thức này mang tới, đó chính là tạo ra những component UI phức tạp và có tính reuse cao.