BEM là một quy ước đặt tên phổ biến cho các class CSS, được sử dụng chúng tôi sử dụng rộng rãi tại Sparkbox. Các khái niệm cơ bản của BEM rất đơn giản và dễ hiểu, nhưng có những lỗi phổ biến cho người mới biết BEM bài viết này giải quyết các vấn đề đó thông qua các ví dụ.

BEM theo ví dụ

 

 

BEM (viết tắt của Block-Element-Modifier) là một chuẩn quy ước đặt tên cho class CSS. Nó đã được chấp nhận rộng rãi và rất hữu ích trong việc viết CSS để dễ đọc, dễ hiểu, và quy mô.

TẠI SAO LÀ BEM

Đặt tên theo BEM cung cấp ba lợi ích cụ thể:

  • Nó truyền đạt mục đích hoặc chức năng.
  • Nó truyền đạt cấu trúc component.
  • Nó thiết lập một mức thấp nhất của đặc tính cho các kiểu selector.

 

LÀM THẾ NÀO NÓ HOẠT ĐỘNG

Tên class BEM bao gồm ba thành phần:

  • 1. Block: Phần tử cha bên ngoài cùng nhất của component được định nghĩa như một khối.
  • 2. Element: Bên trong của một component có thể có nhiều phần tử con gọi là các phần tử.
  • 3. Mỗi một Block hoặc Element có thể có một biểu hiện sự thay đổi bởi một sửa đổi.

Nếu cả ba cùng được sử dụng trong một cái tên nó sẽ giống như thế này:

[block]__[element]--[modifier]

 Sau khi đã giới thiệu ngắn gọn, hãy xem một số ví dụ cụ thể.

CÁC VÍ DỤ

Component không có Elements hoặc Modifier

Các component cơ bản chỉ có một phần tử duy nhất và do đó một class duy nhất sẽ là block.

<button class="btn"></button>

<style>
  .btn {}
</style>

Component có chỉnh sửa

Một component có thể có sự sửa đổi, sự sửa đổi đó nên thực hiện với một modifier class.


<!-- DO THIS -->
<button class="btn btn--secondary"></button>

<style>
  .btn {
    display: inline-block;
    color: blue;
  }
  .btn--secondary {
    color: green;
  }  
</style>  

 

Không được sửa đổi class chính nó. Tăng thêm modifier class chứ không được thay thế class cơ bản.


<!-- DON'T DO THIS -->
<button class="btn--secondary"></button>

<style>
  .btn--secondary {
    display: inline-block;
    color: green;
  }  
</style>  

Component với các Elements

Các component phức tạp hơn sẽ có các element con. Mỗi element con cần được tạo kiểu nên bao gồm một tên class.

 

Một trong những mục đích đằng sau sử dụng BEM là giữ cho đặc tính thấp nhất và nhất quán. Không bỏ qua tên các class từ các phần tử con trong HTML của bạn. Điều đó buộc bạn phải sử dụng các selector làm tăng đặc tính của các element bên trong component ( xem các phần tử imgfigcaption dưới đây). Các class có thể ngắn gọn hơn, nhưng sẽ làm tăng các nguy cơ trong tương lai. Một mục tiêu của BEM là chỉ sử dụng một tên class cho các selector.


<!-- DO THIS -->
<figure class="photo">
  <img class="photo__img" src="me.jpg">
  <figcaption class="photo__caption">Look at me!</figcaption>
</figure>

<style>
  .photo { } /* Specificity of 10 */
  .photo__img { } /* Specificity of 10 */
  .photo__caption { } /* Specificity of 10 */
</style>

<!-- DON'T DO THIS -->
<figure class="photo">
  <img src="me.jpg">
  <figcaption>Look at me!</figcaption>
</figure>

<style>
  .photo { } /* Specificity of 10 */
  .photo img { } /* Specificity of 11 */
  .photo figcaption { } /* Specificity of 11 */
</style>

 

Nếu component của bạn có các element con nhiều cấp, đừng cố gắng dùng tên class để đại diện cho từng cấp. BEM không có mục đích thể hiện chiều sâu của cấu trúc. Một tên class BEM đại diện cho một phần tử con trong component này chỉ nên bao gồm một block cơ bản và tên một element. Trong ví dụ dưới đây, lưu ý rằng photo__caption__quote là một cách sử dụng không chính xác của BEM, trong khi photo__quote thích hơp hơn.



<!-- DO THIS -->
<figure class="photo">
  <img class="photo__img" src="me.jpg">
  <figcaption class="photo__caption">
    <blockquote class="photo__quote">
      Look at me!
    </blockquote>
  </figcaption>
</figure>

<style>
  .photo { }
  .photo__img { }
  .photo__caption { }
  .photo__quote { }
</style>


<!-- DON'T DO THIS -->
<figure class="photo">
  <img class="photo__img" src="me.jpg">
  <figcaption class="photo__caption">
    <blockquote class="photo__caption__quote"> <!-- never include more than one child element in a class name -->
      Look at me!
    </blockquote>
  </figcaption>
</figure>

<style>
  .photo { }
  .photo__img { }
  .photo__caption { }
  .photo__caption__quote { }
</style>

Element có Modifier

Trong một số trường hợp, bạn chỉ muốn thay đổi môt element trong một component. Trong trường hợp này chỉ cần thêm một modifier đối với element cần thay đổi của component đó. Tôi nhận thấy rằng sửa đổi một element sẽ hữu ích hơn sửa đổi các component.


<figure class="photo">
  <img class="photo__img photo__img--framed" src="me.jpg">
  <figcaption class="photo__caption photo__caption--large">Look at me!</figcaption>
</figure>

<style>
  .photo__img--framed {
    /* incremental style changes */
  }
  .photo__caption--large {
    /* incremental style changes */
  }
</style>

 

Thay đổi trên component cho các element có cùng kiểu cơ bản

Nếu bạn muốn chỉnh sửa các element của component theo một định dạng, sau đó bổ sung các modifier của component cơ sở và điều chỉnh kiểu cho mỗi element con một modifier. Điều này làm tăng tính xác thực, nhưng sửa đổi component ở trường hợp này đơn giản hơn nhiều.


<!-- DO THIS -->
<figure class="photo photo--highlighted">
  <img class="photo__img" src="me.jpg">
  <figcaption class="photo__caption">Look at me!</figcaption>
</figure>

<style>
  .photo--highlighted .photo__img { }
  .photo--highlighted .photo__caption { }
</style>

<!-- DON'T DO THIS -->
<figure class="photo">
  <img class="photo__img photo__img--highlighted" src="me.jpg">
  <figcaption class="photo__caption photo__caption--highlighted">Look at me!</figcaption>
</figure>

<style>
  .photo__img--highlighted { }
  .photo__caption--highlighted { }
</style>

 

Tên có nhiều từ

Tên theo BEM sử dụng hai dấu gạch dưới và hai dấu gạch nối thay vì đơn lẻ kiểu như Block-Element-Modifier. Lý do là để các dấu gạch nối đơn có thể sử dụng như các "dấu cách". Các tên class phải đọc được, vì vậy chữ viết tắt không phải lúc nào cùng cần thiết, trừ khi chữ viết tắt có thể hiểu được.


<!-- DO THIS -->
<div class="some-thesis some-thesis--fast-read">
  <div class="some-thesis__some-element"></div>
</div>

<style>
  .some-thesis { }
  .some-thesis--fast-read { }
  .some-thesis__some-element { }
</style>

<!-- DON'T DO THIS -->
// These class names are harder to read
<div class="somethesis somethesis--fastread">
  <div class="somethesis__someelement"></div>
</div>

<style>
  .somethesis { }
  .somethesis--fastread { }
  .somethesis__someelement { }
</style>

 

BEM SẼ KHIẾN BẠN HẠNH PHÚC

Hiện tại nếu bạn không sử dụng BEM, tôi sẽ giới thiệu nó vào dự án tiếp theo của bạn. Nó có thể khác so với những gì bạn đã sử dụng, nhưng tôi tin rằng bạn sẽ nhanh chóng nhìn thấy những lợi ích mà nó sẽ cung cấp cho các dự án lớn và nhỏ. Và hy vọng những ví dụ này sẽ giúp bạn tránh được một số lỗi mà chúng ta thường gặp khi lần đầu sử dụng quy ước đặt tên này.

 

Bài viết được dịch từ :https://seesparkbox.com/foundry/bem_by_example

Đăng ký thực tập Web basic with HTML5, CSS3 and JavaScript tại Techmaster: https://goo.gl/cYzx53