Bem nhau là gì
Đặt tên là 1 trong những vấn đề đau đầu nhất trong khoa học, đặt tên class hay biến, hàm... trong lập trình web của chúng ta cũng vậy. Trước đây thì việc đặt class khá tự do và không có quy chuẩn nào chung, nhưng từ khi BEM ra đời, mọi thứ đã khác đi. Tuy nhiên với ai mới tiếp cận BEM thì chắc chắn sẽ có những băn khoăn, mình viết bài này để giới thiệu 1 số vấn đề mà mình hiểu, mọi người hãy góp ý nếu thấy gì chưa đúng để cùng tìm ra cách sử dụng BEM hợp lý nhất nhé. Show BEM là gì và cách dùng?BEM gồm 3 phần. Block-Elements-Modifiers: Blocks : là thành phần độc lập về mặt chức năng và logic của trang web, block có thể lồng trong nhau và được lặp lại Elements: là các thành phần con trong block Modifiers: bạn hãy hiểu là chúng ta có 1 số kiểu button trong 1 trang web, đa số là màu xanh, ta sẽ cho button mặc định màu xanh, với trường hợp button màu đỏ, ta sẽ thêm hậu tố để phân biệt Các đặt tên theo BEM sẽ như thế này: .block__element--modifier Cách chia block thì các bạn hãy để ý các page, chia page ra thành các phần riêng biệt có thể tái sử dụng ở nhiều nơi cả trong 1 page và nhiều page, nếu nó chỉ có trong 1 page thì có thể đặt tên theo page đó còn nếu nó dùng chung cho nhiều page thì hãy tìm 1 cái tên chung chung, ví dụ block text-box chỉ có trong page giới thiệu thì có thể đặt nó là "text-box-intro" sẽ dễ hình dung, còn nếu nhiều page có cái text-box tương tự thì hãy đặt là "text-box" mà thôi.
Ví dụ ta có block giới thiệu phim đang hot như này, giả sử đặt là film-hot đi , phần khoanh vàng là 1 element: box-info, mọi người có thể đặt là film-hot__box-info. Trong box-info có các element như title phim mình khoanh đỏ, rating..., lúc này chúng ta sẽ đặt là film-hot__title. Các element chỉ cần thể hiện mối quan hệ với block, không cần ràng buộc với thành phần cha bao nóBây giờ chúng ta có 2 nút thế này, cùng background-color, cùng text-color, font, cùng border-radius. Và hầu hết các nút đều có height như nút to, vậy thì chúng ta sẽ đặt 1 block là "btn" với height "cao", font, color, border... mặc định. Khi cần sử dụng tới button nhỏ, chúng ta sẽ đặt là "btn btn--small" và css height khác đi đè lên. Tuy nhiên chúng ta cũng có thể đặt là "btn--small" thôi, lúc này các bạn phải css cho btn--small các thuộc tính base như của bth và btn mặc định các bạn sẽ không đặt height nữa, chỉ css những gì chung giữa các nút mà thôi, mình thì hay sử dụng cách 1 và đó cũng là cách được dùng phổ biến hơn, cách này các bạn cũng có thể css btn chỉ những gì chung nhất, không set height mặc định nữa dù đa phần các nút có height giống nhau. Các bạn nên nhớ là việc đặt class không có đúng hay sai, làm sao cho team làm việc thuận lợi nhất có thể là được. Tuy nhiên thì nó sẽ có vấn đề như này, các nút có height nhỏ chỉ xuất hiện trong trang giới thiệu, còn nút to chỉ xuất hiện trong trang detail, thì lúc này sẽ có 1 cách khác tường minh hơn là các bạn hãy đặt 1 class cha lên tận body hoặc main gì đó to nhất, page-intro và page-detail, lúc này hãy css từ tận page này xuống btn thay vì thêm "--" vào sau btn, người xem sẽ hiểu là "à, cái nút này nó khác là do nằm trong page này". Nếu đó là mục đích khi design thì các bạn nên làm theo cách này, nó sẽ tường minh hơn. Còn nếu các nút thay đổi không phải theo page mà do mục đích ví dụ nút edit thì màu xanh da trời còn nút xóa thì màu đỏ thì các bạn cũng có thể đặt là "btn btn--edit" và "btn--delete" na ná như bootstrap: "btn-warning" đó.
Ví dụ phần phim lẻ mới cập nhật này, hẳn là sẽ có người chia từng phim khoanh vàng thành 1 block, nhưng lại thấy cái bao ngoài giống hệt phần phim bộ phía dưới, chẳng lẽ ta sẽ cho cả phần bao là 1 block và đặt là movie-list -> movie-list__item -> movie-list__title-item (để phân biệt với title của list phim), movie-list__thumbnail-item....? Theo mình thì không nên làm như vậy, BEM nên đặt theo block nhỏ nhất mà đủ bao quát những cái chung và dễ dàng tùy biến. Nếu ta chọn block quá bao quát, quá to, tên các element trong cùng sẽ rất lộn xộn như ví dụ trên. Hãy chia từng phim khoanh vàng là 1 block và cho vào 1 div cha là "movie-list", movie-list sẽ được dùng chung cho cả phần phim bộ phía dưới vì nó tương đồng. Kết quả sẽ như này: movie-list -> movie-item -> movie-item__title, movie-item__sub-title, movie-item__time... Các bạn hãy nhớ rằng BEM là cách đặt tên theo block chứ không phải từ ngoài vào trong, hãy nhìn từ phần tử nhỏ nhất ngược trở ra thay vì cố gắng đặt class từ ngoài vào trong, mình thấy nhiều bạn cố gắng đặt như này: page -> page__wrap -> page__content -> page__content-title, page__content-main. Không nên làm thế, chúng ta không nhất thiết phải sử dụng BEM mọi lúc mọi nơi, chỉ nên sử dụng khi có block, thay vì đặt như trên chúng ta hãy đặt như này: page -> page-wrap -> page-content -> page-title... do page chẳng thể nào là 1 block, các thành phần con của nó không cần đặt theo BEM, tất nhiên đặt cũng chả sao nhưng nó sẽ gặp vấn đề nếu trong cái page__content-main lại có title và nhiều thứ khác, các bạn sẽ đặt theo BEM sao đây? Kết luậnBEM là 1 quy chuẩn đặt tên class chung tuy nhiên các bạn đừng cố áp đặt mọi thứ phải theo BEM, hãy nghĩ thoáng 1 chút nếu không các bạn sẽ mất rất nhiều thời gian đắn đo để đặt tên. Chỉ cần nhớ rằng hãy đặt tên theo block nhỏ nhất có thể, chứ đừng đặt tên từ ngoài vào trong. 1 block hợp lý là 1 block chỉ có block, các con block__element. BEM sẽ tốt khi chúng ta dùng với SCSS, còn nếu bạn chỉ css thường thì cũng nên học dần, nó giúp class tường minh hơn tuy nhìn class khá khó chịu và dù gì các bạn cũng phải dùng scss, sass... sau này thôi, không tránh được. Sẽ có 1 số quan niệm riêng khi mỗi người học về BEM như vấn đề số 2 "btn btn--small" và "btn--small", tuy nhiên không có đúng hay sai, quan trọng nhất là thống nhất team làm như thế nào để dễ phát triển và edit khi cần. Trên đây là những ý kiến của mình về BEM, mọi người cứ thoải mái chém vì mình cũng chỉ là gà mờ thôi, rất mong các cao nhân vào chỉ giáo thêm
Highlight: BEM là viết tắt của Block Element Modifiers – một quy tắc giúp bạn đặt tên các selector của CSS. Chào các bạn, Bạn có bao giờ code CSS mà không biết phải đặt tên class như thế nào không? Mình thì có đấy. Nhất là khi maintain dự án, mất bao nhiêu công mới nghĩ ra được cái tên hay thì lại bị người người trước dùng mất rồi. Tự nghĩ Code CSS thì nên tập trung vào việc căn chỉnh các thuộc tính, chứ không nên mất nhiều thời gian vào cách đặt tên, nên mình đã đi tìm hiểu xem có cái quy tắc nào trong cách đặt tên không, để rồi cứ theo quy tắc là làm, đỡ phải nghĩ nhiều. Sau một hồi lục sục trên mạng, mình thấy có cái quy tắc BEM này khá hay nên viết bài để chia sẻ tới mọi người. I. Quy tắc BEM là gì?BEM là viết tắt của Block Element Modifiers – một quy tắc giúp bạn đặt tên các selector của CSS. Block Element Modifiers nghĩa là “Khối – Phần tử – Biến thể”, dịch ra Tiếng Việt nghe không được sát nghĩa và có vẻ không “chuyên nghiệp”, nên thôi mình cứ để Tiếng Anh nhé. Với quy tắc BEM, nó sẽ chia các class css ra làm 3 loại:
Rắc rối nhỉ, thôi thì xem cái ví dụ này để dễ hiểu hơn bạn nhé. CSS viết theo quy tắc BEM /* class định nghĩa một block */ .product { } /* class định nghĩa element của block */ .product__title { } .product__description { } .product__image { } /* class định nghĩa các "biến thể" của block */ .product--style-1 { } .product--big { } .product--small { } .product__title--style-1 { } HTML sử dụng CSS viết theo quy tắc BEM Iphone 11 Pro
Siêu đắt
Từ hai đoạn code trên bạn có thể thấy:
Tổng quát lại, chúng ta có thể thấy một class viết theo quy tắc BEM sẽ có cấu trúc như sau Block__Element--ModifierVới cách đặt tên kiểu này, các css selector sẽ khó mà trùng nhau được. II. Lợi ích khi sử dụng BEMLợi ích mà ai cũng thấy được ngay đó là BEM giúp chúng ta giảm khả năng 2 css selector bị trùng nhau – giống như ngay từ đầu mình đề cập. Nhưng ngoài ra, BEM còn có một số lợi ích khác:
Ngoài các lợi ích kể trên, BEM còn phù hợp để triển khai với SCSS Ví dụ: Vẫn là đoạn CSS ở ví dụ trên, nhưng giờ mình viết theo SCSS. .product { &__title { &--style-1 { } } &__description { } &__image { } &--style-1 { } &--big { } &--small { } }III. Một số ý kiến không đồng tình với quy tắc BEMDù có nhiều lợi ích, nhưng có nhiều người không thích dùng quy tắc này vì Nó dài và xấu Mình công nhận điều này, nếu không cận thận bạn sẽ có .Mot-cai-class__dai--ngoang-ngoang-the-nay. Nhưng dài mà mang đủ ý nghĩa, đảm bảo không bị trùng thì cũng không sao. Còn xấu thì… nhìn nhiều khắc quen. Nó có vẻ không cần thiết Quay trở lại với ví dụ ở phần đầu, mình có thể viết CSS không tuân theo quy tắc BEM và vẫn đáp ứng được một số lợi ích của BEM như sau: .product { } .product .title { } .product .description { } .product .image { } .product.style-1 { } .product.big { } .product.small { } .product .title.style-1 { } Nhìn còn có vẻ gọn ngàng hơn đấy chứ, nhưng khi dự án phát triển tới một “cảnh giới” nhất định thì liệu bạn có chắc chắn các class sẽ không bị đặt tên chồng chéo không? Giả sử ở đâu đó trong project đã có ai đó định nghĩa các class .title, .image, .description rồi thì sao? // Ai đó đã định nghĩa trước các selector thế này .title { } .description { } .image { } Không biết bạn có cảm thấy không hài lòng với BEM ở chỗ nào không? IV. Tổng kếtTổng kết lại thì:
Còn bạn thế nào, bạn có thấy BEM cần thiết trong dự án của mình không? Hãy để lại comment cho mình biết với. |