BEM: phương pháp tổ chức CSS hiệu quả và linh hoạt nhất

BEM: phương pháp tổ chức CSS hiệu quả và linh hoạt nhất

1,270 lượt xem
CHIA SẺ

CSS là một phần quan trọng trong phát triển web, nhưng khi dự án phức tạp, quản lý mã CSS trở nên khó khăn. Chuẩn BEM  giúp tổ chức và quản lý CSS một cách hiệu quả. Bài viết này khám phá BEM, cách áp dụng nó và lợi ích mà nó mang lại cho việc phát triển web.

Trong bài viết này, chúng ta sẽ khám phá sâu hơn về chuẩn BEM và cách nó có thể cải thiện quá trình phát triển web. Cùng tìm hiểu cách áp dụng BEM trong việc viết CSS, những lợi ích mà nó mang lại, cùng với những quy tắc và bước tiếp cận tốt nhất để sử dụng BEM một cách hiệu quả. Hãy bắt đầu ngay bây giờ!

BEM là gì?

BEM là viết tắt của Block – Element – Modifier, là tiêu chuẩn quy ước đặt tên cho các class trong CSS được phát triển bởi team Yandex. BEM giúp cho việc coding trở nên dễ hiểu, dễ đọc, dễ bảo trì và dễ mở rộng hơn khi code CSS.

bem-la-gi

Block: Là thành phần cấp lớn nhất của một component

Element: Là những phần tử bên con bên trong Block

Modifier: Là những biến thể khác nhau của Block, Hoặc nói cách khác Modifier là tập hợp những style override hoặc thay đổi style ban đầu của Block

Quy ước đặt tên theo BEM

Mục tiêu lớn nhất của BEM là giúp các Developer hiểu rõ hơn về mối quan hệ giữa HTML và CSS trong một dự án. 

  • Tên của Block, Element và Modifier có thể bao gồm các chữ cái Latinh, chữ số và cả dấu gạch ngang.
  • Tên của Element được đặt với công thức: tên block cộng với hai dấu gạch dưới __, cộng với tên element.
    VD: .block__element
  • Tên của Modifier được đặt với công thức: tên block hoặc element cộng với hai dấu gạch ngang –-, cộng với tên modifier.

HTML

<a class="btn btn--big btn--orange" href="#">
    <span class="btn__price">$10</span>
    <span class="btn__text">Buy</span>
</a>

CSS

// Block component
.btn {}

// Element là phần tử con bên trong Block
.btn__price {}
.btn__text {}

// Modifier là những thay đổi style của Block
.btn--organge {}
.btn--big {}

 

Vì sao nên chọn BEM

  • Với BEM việc đặt tên class css không còn là nỗi lo: Không còn phải đau đầu mỗi khi suy nghĩ ra tên class cho component nữa.
  • BEM giúp cho team làm việc với nhau dễ dàng hơn: Khi Teamwork với nhau, mỗi người đều sẽ có một cách đặt tên class riêng và rất dễ bị conflict với nhau. Việc sử dụng BEM sẽ bị loại bỏ vấn đề này vì cả team sẽ phải tuân thủ theo quy ước chung khi làm việc.
  • Modules: Các class của mỗi Block sẽ không bị ảnh hưởng gì bởi các yếu tố khác, thế CSS của class này sẽ không ảnh hưởng đến class khác.
  • Tái sử dụng: Có thể soạn các block riêng biệt và sử dụng lại chúng một cách thuận tiện và giảm số lượng code CSS.
  • Cấu trúc: BEM cung cấp cho CSS một cấu hình vững chắc, đơn giản và rất dễ hiểu
  • Khi đọc source HTML chúng ta có thể nhanh chóng nhận biết được các phần tử nào phụ thuộc vào phần tử khác ( .block__element phụ thuộc vào .block)
  • Designer và developer có thể thống nhất cách đặt tên các component để dễ dàng giao tiếp với nhau hơn khi teamwork.

Nhược điểm của BEM

nhuoc-diem-cua-bem

  • Đặt tên lớp dài và phức tạp: Nhược điểm của BEM là việc đặt tên lớp có thể trở nên dài và phức tạp. Cấu trúc tên lớp theo quy tắc BEM có thể làm cho mã HTML và CSS trở nên khó đọc và hiểu, đặc biệt là khi có nhiều Block, Element và Modifier.
  • Quản lý phức tạp với các thành phần lồng nhau: Khi sử dụng BEM trong các thành phần lồng nhau, việc quản lý các tên lớp có thể trở nên phức tạp. Điều này có thể dẫn đến việc gặp khó khăn trong việc xác định cấu trúc và quan hệ giữa các thành phần.
  • Rủi ro xung đột tên lớp:  Do BEM yêu cầu đặt tên class cụ thể cho từng Block, Element và Modifier, có thể xảy ra rủi ro xung đột việc đặt tên class giữa các thành viên trong team.

Biến thể của BEM

Ví dụ:

<a class=" btn btn--primary btn--large btn--font-12 ....">

Biến thể của BEM giúp cho việc viết code được “sạch đẹp” hơn và có sự linh hoạt để cấu hình bất kỳ component nào. Nó phù hợp với component có nhiều sửa đổi như: button, icon, typography

Biến thể mới sẽ được viết như sau

<a class=" block -modifier">

Biến thể modifier sẽ bắt đầu bằng dấu gạch ngang  

 Ví dụ:

<!-- Icon -->
<i class="e-icon -icon-envato -color-green -size-xl -margin-right"></i>
<!-- Typography -->
<h2 class="t-heading -size-m -color-light">Heading</h2>
<p class="t-body -size-s">Paragraph</p>
<!-- Inputs -->
<input class="f-input -type-string -width-full">
<!-- Notifications -->
<div class="alert-box -type-success">
        <div class="alert-box__icon">  
            <i class="e-icon -icon-ok"></i>
        </div>
 	<div class="alert-box__message">
            <p class="t-body -size-m h-remove-margin">Success!!</p>
        </div>
</div>

 

Ví dụ thực tế của BEM

Ta có design như sau:

Design của chúng ta có 4 button với 4 style khác nhau.

HTML sẽ như sau

<button class="button">
 <span class="button__text">Button</span>
</button>
<button class="button button--red">
 <span class="button__text">Facebook</span>
 <i class="button__icon fab fa-facebook-f"></i>
</button>
<button class="button button--purple button--revert">
 <span class="button__text">Download</span>
 <i class="button__icon fas fa-cloud-download-alt"></i>
</button>
<button class="button button--large button--purple button--revert">
 <span class="button__text">Download</span>
 <i class="button__icon fas fa-cloud-download-alt"></i>
</button>

Có thể thấy ở button số 4 có đến 3 Modifier điều này dẫn đến code HTML sẽ khá dài và khó đọc. Vì lý do đó chúng ta sẽ tạo ra 1 biến thể của Modifier gồm style của cả 3

<button class="button -large-purple-revert">
 <span class="button__text">Download</span>
 <i class="button__icon fas fa-cloud-download-alt"></i>
</button>

CSS: 

.button {
 display: inline-flex;
 justify-content: center;
 align-items: center;
 gap: 1.5rem;
 font-size: 1rem;
 padding: 1rem 3rem;
 margin: 1rem;
 font-family: Arial,sans-serif;
 color: #ffffff;
 font-weight: bold;
 border-radius: 0.5rem;
 background-color: #3290ff;
  &__text {
   /**/
 }
 &__icon {
   /**/
 }
 &--large {
   font-size: 1.5rem;
   padding: 1.25rem 4rem;
 }
 &--red {
   background-color: #f46700;
 }
 &--purple {
   background-color: #9800f4;
 }
 &--revert {
   flex-direction: row-reverse;
 }
 &.-large-purple-revert {
   font-size: 1.5rem;
   padding: 1.25rem 4rem;
   background-color: #9800f4;
   flex-direction: row-reverse;
 }
}

Link Demo

Các lưu ý khi làm việc với BEM

  • Khi bắt đầu 1 dự án chúng ta cần xem rõ guide và style những component dùng chung để có thể tái sử dụng được và tồn tại độc lập với các component khác. 
  • Đặt tên selector theo chức năng hoặc vai trò của component (VD: .header, .footer, .button, …)
  • Một element thì chỉ kế thừa từ một component
  • Làm gì nếu Block có cấu trúc phức tạp và các Elements của nó được lồng vào nhau? Các class CSS như block__elem1__elem2__elem3 trông thật đáng sợ.

Theo phương pháp BEM, cấu trúc khối nên được làm phẳng; không cần phản ánh cấu trúc DOM lồng nhau của Block.

<div class="block">
    <div class="block__element1">
        <div class="block__element2">
            <div class="block__element3"></div>
        </div>
    </div>
</div>
<!-- Hoặc -->
<div class="block">
    <div class="block__element1">
        <div class="block__element2"></div>
    </div>
    <div class="block__element3"></div>
</div>

Vì vậy, tên class cho trường hợp này sẽ là:

.block {}
.block__element1 {}
.block__element2 {}
.block__element3 {}

Việc viết như vậy các class trông đẹp hơn nhiều, nó làm cho các Element chỉ phụ thuộc vào một Block. Những thay đổi của cấu trúc khối DOM sẽ không cần những thay đổi tương ứng đối với code CSS.

BEM trong SASS

Ở ví dụ trên là cách viết cơ bản của BEM trong SASS, nâng cao hơn thể tạo ra các mixins cho BEM để tối ưu thời gian coding hơn.

Tạo ra các mixins:

/* Block Element */
/* @param {String} $element - Tên của Element */
@mixin element($element) {
   &__#{$element} {
       @content;
   }
}


/* Block Modifier */
/* @param {String} $modifier - Tên của Modifier */
@mixin modifier($modifier) {
   &--#{$modifier} {
       @content;
   }
}

Sử dụng trong SASS

.person {
   @include element('hand') {
       /* Person hand */
   }
   @include element('leg') {
       /* Person leg */
   }
   @include modifier('male') {
       /* Person male */
       @include element('hand') {
           /* Person male hand */
           @include modifier('left') {
               /* Person male left hand */
           }
           @include modifier('right') {
               /* Person male right hand */
           }
       }
   }
}

Code CSS được sinh ra

/*CSS được tạo ra*/
.person__hand {
        /* Person hand */
}
.person__leg {
        /* Person leg */
}
.person--male {
 	/* Person male */
}
.person--male__hand {
        /* Person male hand */
}
.person--male__hand--left {
        /* Person male left hand */
}
.person--male__hand--right {
        /* Person male right hand */
}

 

Kết luận

Tóm lại chuẩn BEM trong CSS giúp cho chúng ta có thể tiết kiệm được thời gian trong khi phát triển web. Ngoài ra BEM còn giúp việc teamwork trở nên dễ dàng và hạn chế conflict. Hy vọng bài viết này sẽ giúp bạn hiểu hơn về BEM cũng như áp dụng vào dự án một cách đơn giản nhất. Thanks for reading!



Chia sẻ

Theo dõi
Thông báo cho
guest
0 Góp ý
Inline Feedbacks
View all comments

Tiếp theo

CSS Selector là gì? Những cách viết CSS có thể bạn chưa biết.

CSS Selector là gì? Những cách viết CSS có thể bạn chưa biết.

3,822 lượt xem
3 năm trước
Vì sao cần reset CSS khi bắt đầu một project

Vì sao cần reset CSS khi bắt đầu một project

5,428 lượt xem
5 năm trước
Share plugin trang trí noel cho website wordpress

Share plugin trang trí noel cho website wordpress

6,832 lượt xem
6 năm trước
Thay đổi size ảnh thoải mái không lo “bị méo” với thuộc tính object-fit trong css

Thay đổi size ảnh thoải mái không lo “bị méo” với thuộc tính object-fit trong css

23,937 lượt xem
7 năm trước
Tổng hợp các thuộc tính cho text trong css

Tổng hợp các thuộc tính cho text trong css

7,561 lượt xem
7 năm trước
Xem thêm
0
Would love your thoughts, please comment.x