Điều gì làm cho BEM tốt hơn so với việc sử dụng ngôn ngữ biểu định kiểu lồng nhau như LESS?


27

Một đồng nghiệp của tôi đang thúc đẩy mạnh mẽ phương pháp BEM (Bộ điều chỉnh phần tử khối ) cho CSS trong một dự án mà anh ấy đang hỗ trợ và tôi không thể hiểu điều gì làm nó tốt hơn LESS CSS mà chúng tôi đã viết trong nhiều năm.

Ông tuyên bố "hiệu suất cao hơn", nhưng tôi không thể tưởng tượng hiệu suất thậm chí có thể quan trọng như thế nào đối với các loại ứng dụng web chúng tôi viết trong cửa hàng mã này. Chúng tôi sẽ không tạo Twitter hay Facebook ở đây. Tôi sẽ rất ngạc nhiên nếu các ứng dụng sử dụng cao nhất của chúng tôi có hơn 10000 lượt truy cập mỗi tháng và hầu hết đều dưới 1000.

Ông tuyên bố "dễ đọc" và "tái sử dụng", nhưng theo tôi thì LESS đã làm điều đó tốt hơn nhiều . Và tôi cảm thấy rằng BEM đã xử lý lỗi đánh dấu rất tệ với hàng tá các ký tự phụ dành riêng cho các tên lớp siêu dài này mà nó hoàn toàn làm giảm khả năng đọc.

Ông tuyên bố "CSS lồng nhau là một mô hình chống." "Chống mẫu" thậm chí có nghĩa là gì và tại sao CSS lồng nhau lại xấu?

Ông tuyên bố rằng "tất cả mọi người đang chuyển sang sử dụng BEM, vì vậy chúng tôi cũng nên như vậy." Quầy của tôi là "Nếu mọi người nhảy khỏi một cây cầu, bạn sẽ đi theo chứ?" Nhưng anh ấy vẫn hoàn toàn kiên quyết về điều này.

Ai đó có thể vui lòng giải thích chi tiết những gì làm cho BEM tốt hơn LESS không? Đồng nghiệp của tôi hoàn toàn thất bại trong việc thuyết phục tôi, nhưng tôi không biết liệu tôi có lựa chọn nào khác ngoài việc làm theo không. Tôi thực sự muốn đánh giá cao BEM hơn là chấp nhận một cách miễn cưỡng.


1
BEM và LESS phục vụ các mục đích khác nhau. Tôi sử dụng cả BEM và LESS.
zzzzBov

4
Lưu ý rằng BEM không chủ yếu là về CSS - đó là về việc xác định các mẫu được đóng gói định kỳ trong thiết kế của bạn và thu thập mọi thứ cần thiết cho khối đó (hành vi, mẫu, kiểu) ở một vị trí trung tâm. Ngay cả khi chỉ giới hạn ở CSS, BEM vẫn là một cách tuyệt vời để sắp xếp các kiểu của bạn và ngăn chặn các xung đột tên một cách đáng tin cậy. Điều đó hoàn toàn độc lập với các bộ tiền xử lý như LESS hoặc SASS, vốn chỉ là ngôn ngữ tạo kiểu hiệu quả hơn CSS đơn giản vì chúng cung cấp các macro và biến và ký hiệu tốc ký và tất cả các loại tính năng hay. LESS = win, BEM = win, nhưng LESS × BEM = win²!
amon

Câu trả lời:


29

Một đồng nghiệp của tôi đang thúc đẩy mạnh mẽ phương pháp BEM (Bộ điều chỉnh phần tử khối) cho CSS trong một dự án mà anh ấy đang hỗ trợ và tôi không thể hiểu điều gì làm nó tốt hơn CSS LESS mà chúng tôi đã viết trong nhiều năm.

BEM là một phương pháp CSS. Những người khác bao gồm OOCSS và SMACSS. Các phương pháp này được sử dụng để viết mã mô-đun, có thể mở rộng, có thể tái sử dụng, hoạt động tốt ở quy mô.

LESS là một bộ tiền xử lý CSS. Những người khác bao gồm Sass và bút stylus. Các bộ tiền xử lý này được sử dụng để chuyển đổi các nguồn tương ứng của chúng thành CSS mở rộng.

BEM và LESS không thể so sánh là "tốt hơn" so với nhau, chúng là những công cụ phục vụ các mục đích khác nhau. Bạn sẽ không nói rằng một cái tuốc nơ vít tốt hơn búa, trừ khi xem xét tiện ích để giải quyết một vấn đề cụ thể.

Ông tuyên bố "hiệu suất cao hơn" ...

Hiệu suất sẽ cần được đo giữa một kiểu CSS cổ điển:

.widget .header

và phong cách BEM của:

.widget__header

nhưng nói chung, hiệu suất của bộ chọn CSS không phải là nút cổ chai và không cần phải tối ưu hóa.

"Hiệu suất" của BEM thường liên quan đến mã viết hiệu suất của nhà phát triển. Nếu phương pháp BEM được sử dụng một cách nhất quán và chính xác, thì các nhóm nhà phát triển có thể đồng thời tạo ra các mô-đun riêng biệt mà không có xung đột kiểu.

Ông tuyên bố "dễ đọc" và "tái sử dụng" ...

Tôi không biết rằng tôi sẽ nói với một nhà phát triển mới rằng BEM dễ đọc hơn. Tôi có thể nói rằng nó cung cấp một số hướng dẫn được xác định rõ về ý nghĩa và cấu trúc của các lớp.

Nhìn thấy một lớp học như

.foo--bar__baz

Nói với tôi rằng có một fookhối ở bartrạng thái và chứa một bazphần tử.

Tôi hoàn toàn có thể nói rằng BEM có thể tái sử dụng nhiều hơn một mô hình cổ điển.

Nếu hai nhà phát triển tạo các khối ( foobar) và cả hai khối đó đều có tiêu đề, họ có thể sử dụng lại các khối của mình một cách an toàn trong các bối cảnh khác nhau mà không lo bị va chạm khi đặt tên.

Đó là bởi vì, trong một bối cảnh cổ điển, .foo .heading.bar .headingsẽ xung đột, và đưa ra một xung đột đặc thù cần được giải quyết, có thể trên cơ sở từng trường hợp cụ thể.

Trong một trang web BEM, các lớp sẽ .foo__heading.bar__headingkhông bao giờ xung đột.

Ông tuyên bố "CSS lồng nhau là một mô hình chống." "Chống mẫu" thậm chí có nghĩa là gì và tại sao CSS lồng nhau lại xấu?

"Chống mẫu" là một mẫu mã hóa mà các nhà phát triển thiếu kinh nghiệm có thể học và sử dụng dễ dàng hơn so với một giải pháp thay thế phù hợp hơn.

Theo như lý do tại sao CSS lồng nhau là xấu: Nesting làm tăng tính đặc hiệu của bộ chọn. Độ đặc hiệu càng cao, càng mất nhiều công sức để ghi đè. Các nhà phát triển thiếu kinh nghiệm thường lo lắng rằng CSS của họ có thể ảnh hưởng đến nhiều trang, vì vậy họ sử dụng các công cụ chọn như:

#something .lorem .ipsum .dolor ul.sit li.amet a.more

Khi một nhà phát triển có kinh nghiệm sẽ lo lắng rằng CSS của họ có thể không ảnh hưởng đến nhiều trang, vì vậy họ sử dụng các công cụ chọn như:

.more

Ông tuyên bố rằng "mọi người đều hướng tới việc sử dụng BEM, vì vậy chúng tôi cũng nên như vậy." ...

Đó là một ngụy biện bandwagon , vì vậy bỏ qua đó là một cuộc tranh luận xấu. Đừng rơi vào bẫy ngụy biện , bởi vì một lập luận xấu trong việc hỗ trợ BEM không phải là lý do để tin rằng BEM không thể tốt.

Ai đó có thể vui lòng giải thích chi tiết những gì làm cho BEM tốt hơn LESS không?

Tôi đã đề cập đến điều này trước đây, BEM & LESS không thể so sánh được. Táo và cam, v.v.

Đồng nghiệp của tôi hoàn toàn thất bại trong việc thuyết phục tôi, nhưng tôi không biết liệu tôi có lựa chọn nào khác ngoài việc làm theo không.

Tôi khuyên bạn nên xem OOCSS, SMACSS và BEM, và cân nhắc ưu và nhược điểm của từng phương pháp ... như một đội . Tôi sử dụng BEM vì tôi thích sự nghiêm ngặt của nó trong định dạng và không bận tâm đến các công cụ chọn xấu xí, nhưng tôi không thể nói cho bạn biết cái gì phù hợp với bạn hoặc cho nhóm của bạn. Đừng để một cá nhân thẳng thắn chạy chương trình. Nếu bạn không thoải mái với BEM, hãy lưu ý rằng có những lựa chọn thay thế khác có thể dễ dàng hơn cho nhóm của bạn để hỗ trợ. Bạn có thể cần bảo vệ vị trí của mình với đồng nghiệp, nhưng về lâu dài nó có thể sẽ có tác động tích cực đến kết quả của các dự án của bạn.

Tôi thực sự muốn đánh giá cao BEM hơn là chấp nhận một cách miễn cưỡng.

Tôi đã viết một câu trả lời trên StackOverflow mô tả cách BEM hoạt động . Điều quan trọng cần hiểu là bộ chọn lý tưởng của bạn nên có tính đặc hiệu 0-0-1-0để chúng dễ ghi đè và mở rộng.

Chọn sử dụng BEM không có nghĩa là bạn cần từ bỏ BÀI HỌC! Bạn vẫn có thể sử dụng các biến, bạn vẫn có thể sử dụng @imports và chắc chắn bạn có thể tiếp tục sử dụng lồng nhau. Sự khác biệt là bạn muốn đầu ra được kết xuất trở thành một lớp duy nhất, chứ không phải là một chuỗi con cháu.

Nơi bạn có thể đã có

.widget {
    .heading {
        ...
    }
}

Với BEM bạn có thể sử dụng:

.widget {
    &__heading {
        ...
    }
}

Ngoài ra, vì BEM xoay quanh các khối riêng lẻ, bạn có thể dễ dàng tách mã thành các tệp riêng biệt. widget.lesssẽ chứa các kiểu cho .widgetkhối, trong khi component.lesssẽ chứa các kiểu cho .componentkhối. Điều này giúp tìm nguồn dễ dàng hơn cho bất kỳ lớp cụ thể nào, mặc dù bạn vẫn có thể muốn sử dụng bản đồ nguồn.


4
@CoreDumpError, vấn đề là khi bạn bắt đầu lồng các mô-đun trong các mô-đun. "Mỗi nhà phát triển chỉ có thể lồng mã của một tiện ích cụ thể của họ sâu hơn một cấp" không hoàn toàn chính xác, mỗi nhà phát triển phải lồng mã của tiện ích cụ thể của họ sâu hơn và sâu hơn nếu không đặt tên cho các xung đột theo cách nói chung là vô tình. Cách duy nhất để tránh xung đột đặt tên là với một số loại không gian tên và BEM cung cấp một cách dễ dàng để các lớp không gian tên nhất quán.
zzzzBov

3
@CoreDumpError, Hãy xem xét ví dụ này . Một tác giả viết mà không có BEM cần phải nỗ lực thêm để xác minh mọi sự kết hợp của mọi mô-đun có thể được thêm vào trong mô-đun của họ. Một tác giả sử dụng BEM không.
zzzzBov

1
@CoreDumpError, chắc chắn là như vậy. Tôi thấy BEM dễ dàng đào tạo các nhà phát triển mới và nó giúp dễ dàng đánh giá mã, nhưng SMACSS và OOCSS là những lựa chọn thay thế tốt. Tôi rất khuyên bạn nên xem xét các lựa chọn đó như là một thay thế. Tôi sẽ nói rằng tôi sử dụng BEM cho sự phát triển của chính mình để tôi không xung đột với chính mình, đặc biệt là với tôi trong tương lai, người ngu ngốc và quên đi mọi thứ.
zzzzBov

1
Tôi thấy BEM là tuyệt vời trên bất kỳ dự án nào liên quan đến bất kỳ loại phức tạp nào là css. Bạn có thể có một trang web nằm trên WordPress và chỉ sử dụng Javascript để kích hoạt mọi thứ khi cuộn, nhưng vẫn phức tạp như một ứng dụng web trong css. Điều quan trọng là không rơi vào cái bẫy suy nghĩ 'trang web của tôi không phức tạp' chỉ vì hầu hết mọi thứ đều hoàn toàn trong lĩnh vực trực quan (giống như nhiều trang web tiếp thị làm)
Toni Leigh

1
@CoreDumpError hầu hết các dự án trước đây của tôi đều là những nỗ lực cá nhân và tôi đã đến với nhiều BEM theo cách riêng của mình: tính cụ thể và bộ chọn duy nhất. Duy trì một cơ sở mã là một vấn đề lớn trở nên cực kỳ rõ ràng với BEM. Mã là bảo trì. Xây dựng mọi thứ thật dễ dàng. Giữ lại các mẫu hoàn hảo là khó, đặc biệt là sau một vài tháng ra khỏi codebase. Vấn đề cụ thể hợp chất theo thời gian. Những lợi ích áp dụng cho bất kỳ nhóm kích thước IMO!
Yuji Tomita

8

Chỉnh sửa 2017

Nếu bạn đang đọc điều này vào năm 2017, các bóng đa năng DOM bóng và DOM bóng, cộng với các thành phần giải quyết tất cả các vấn đề này, trong khi giữ cho mã của bạn nhỏ, chặt chẽ và mô-đun. Không sử dụng BEM trên IMO dự án greenfield.

Thay vì BEM, chúng tôi có các công cụ như ViewEncapsulation, Polyme, StyledJSX, SASS Modules, Kiểu dáng, v.v.

Cân nhắc sử dụng BEM nếu bạn không có kiến ​​trúc hướng thành phần; nếu bạn có mã kế thừa để hỗ trợ; hoặc nếu bạn chỉ chết khi làm mọi thứ bằng tay mà không cần dụng cụ.


BEM làm cho kiểu dáng của bạn độc lập với lồng nhau DOM của bạn. Nó thực hiện điều này bằng cách cung cấp cho mọi phần tử mà bạn có thể muốn tạo kiểu cho một thuộc tính lớp ass lớn có khả năng là duy nhất trên trang của bạn. Hầu hết các kiểu dáng sau đó được thực hiện trên các lớp học.

Điều này làm cho mã của bạn trở nên mô đun hơn, bởi vì lồng không còn được tính đến, với chi phí rất lớn về tính dài dòng.

Không có BEM

Không có BEM, chúng tôi có thể viết điều này:

<div class="widget">
  <a>Hello!</a>
  <ul>...</ul>
</div>

Kiểu CSS tiêu chuẩn có thể trông như thế này:

.widget {
  border: 1px solid red;
}

.widget a {
  color: green;
}

Điều tương tự với SASS sẽ như thế này:

.widget {
  border: 1px solid red;
  a {
    color: green;
  }
}

Nếu bạn là một nhóm nhỏ nơi mọi người có thể mã CSS theo tiêu chuẩn cao và dự án đủ nhỏ để bạn có thể duy trì nhận thức đầy đủ về nó, thì đây là một giải pháp tốt và hợp lý.

Với BEM

Tuy nhiên, nếu mã của bạn trở nên lớn hơn và bạn có một nhóm khả năng hỗn hợp lớn, đây có thể không phải là một giải pháp đơn giản như vậy. Điều gì nếu bạn muốn neo xanh trong một widget khác chẳng hạn. Vì vậy, chúng tôi làm cho neo mô-đun, và loại bỏ các bộ chọn hậu duệ.

Bây giờ HTML của chúng tôi dài dòng hơn nhiều:

<div class="widget">
  <a class="widget__anchor">Hello!</a>
  <ul class="widget__ul">...</ul>
</div>

CSS của chúng tôi không có bộ chọn hậu duệ:

.widget {
  border: 1px solid red;
}

.widget__anchor {
  color: green;
}

Nhưng bây giờ chúng ta có thể làm điều này:

<div class="widget__2">
  <a class="widget__anchor">Hello!</a>
</div>

Các widget__anchor là mô-đun. Không chắc là một định nghĩa khác về .widget__anchor sẽ tồn tại trên trang.

đánh đổi:

BEM:

  • Cung cấp cho bạn nhiều mã mô-đun. Bạn có thể lấy bất kỳ mảnh trong sự cô lập.
  • Cho phép mọi người viết CSS. Bạn không cần phải biết về kiểu dáng chính và ghi đè tùy chỉnh. Trong một đội ngũ lớn, điều này là tốt đẹp.
  • Loại bỏ bất kỳ vấn đề cụ thể.
  • Dài hơn đáng kể.

CSS tiêu chuẩn (dựa trên việc sử dụng các bộ chọn hậu duệ):

  • Có nghĩa là phong cách của bạn phụ thuộc vào bối cảnh.
  • Yêu cầu nhận thức về dòng thác. Mã ở một nơi có thể ảnh hưởng đến mã ở nơi khác. Trong một nhóm nhỏ đây là một điều tốt.
  • Có thể bị các vấn đề cụ thể mà nhà phát triển mới có thể khó gỡ lỗi.
  • Là chặt chẽ hơn đáng kể.

Cách thứ ba - Thành phần thực.

Nếu bạn đang sử dụng một cái gì đó như React, Angular 2 hoặc bất kỳ framewords hiện đại nào khác, bạn có một giải pháp khác. Bạn có thể sử dụng công cụ để thực thi đóng gói.

Ví dụ này sử dụng React và StyledJSX, nhưng có nhiều tùy chọn. Đây là một widget:

const Widget = () => 
  <div>
    <a>Hello</a>
  </div>
  <style jsx>
    div {border:red }
    a { background: pink }
  </style>

Sau đó, bạn sẽ sử dụng các tiện ích mới như thế này:

<Widget />

Tất cả các kiểu được khai báo trong widget sẽ được đóng gói và sẽ không áp dụng cho các thành phần bên ngoài thành phần. Chúng tôi có thể tự do chỉ cần tạo kiểu divatrực tiếp mà không phải lo lắng về việc vô tình tạo kiểu bất cứ thứ gì khác trên trang.


1
Ưu và nhược điểm mà không ủng hộ bất kỳ bên nào, tôi thích nó.
Adrian Moisa

Tôi nghĩ có điều gì đó thực sự buồn khi nói "hãy viết mã của bạn như thế này để những người không hiểu về tầng có thể hiểu được nó". Nó giống như nói "Tôi viết mã của mình mà không có bất kỳ mảng nào vì một trong những thành viên cơ sở của nhóm không hiểu cách thức hoạt động của mảng". Cá nhân tôi thích phương pháp cô đọng hơn, ưu tiên cho mặt tự nhiên của các tầng kiểu xếp tầng.
Matt Fletcher

@MattFletcher - Tôi nghĩ đó là vấn đề về quy mô dự án. Dòng thác vốn là toàn cầu. Bạn đặt giá trị, sau đó ghi đè và ghi đè xuống qua cây. Nếu bạn có một dự án nhỏ hơn với khả năng hiển thị đầy đủ thì điều này là tốt, nhưng trên một dự án lớn hơn, nó trở nên dễ vỡ. Mọi người trở nên sợ thay đổi mọi thứ vì một sự thay đổi cao hơn tầng thác phá vỡ những điều ngẫu nhiên ở những nơi khác. Đóng gói thành phần thực sự tốt đẹp trên các dự án lớn hơn. Tất cả mọi thứ chỉ hoạt động.
siêu sáng

2

Không có cách tiếp cận nào là hoàn hảo. IMHO, chúng ta sẽ có được những phần tốt nhất của từng phương pháp (BEM, SMACSS, OOCSS, DRY). Sử dụng SMACSS để tổ chức cấu trúc thư mục của bạn trong CSS- đặc biệt để xác định phân tích mức logic của toàn bộ CSS. DRY để tạo thư viện tiện ích của bạn hoặc có thể là thư viện sửa đổi phổ biến đôi khi được sử dụng cùng với các lớp dựa trên BEM. OOCSS cho các thành phần. Và BEM cho các thành phần nhỏ hoặc các thành phần phụ. Ở đó bạn có thể phân phối sự phức tạp và có được tự do làm việc trong một nhóm lớn.

Bất cứ điều gì khi sử dụng mà không hiểu bản chất của nó sẽ dẫn đến kết quả xấu.

Mặc dù BEM là cách tiếp cận tốt cho các đội lớn hơn, nhưng nó cũng có một số nhược điểm. 1. Đôi khi nó dẫn đến tên rất dài trong cấu trúc HTML lớn. Kết quả kích thước tệp CSS lớn. 2. Đối với các html lồng nhau có nhiều hơn 2-3 cấp độ, việc xác định tên trở nên đau đầu.

Giải quyết xung đột có thể được quản lý dễ dàng nếu chúng ta nghĩ về cấu trúc thành phần cùng với một bộ kiểu cơ sở rất cơ bản. Đó chỉ là sự kế thừa hai cấp độ. Mỗi phần tử bên trong một thành phần sẽ có quy tắc kiểu toàn cục hoặc cụ thể cho thành phần đó. Đây là một trong những lựa chọn dễ dàng hơn.


Lập luận cực kỳ tốt. Các nhà phát triển nên có thể tự suy nghĩ và phân tích phạm vi của vấn đề. Chỉ cần mù quáng làm theo phương pháp vẫn dẫn bạn đến rắc rối. Tôi có những đồng nghiệp không xem xét ảnh hưởng của những thay đổi của họ trên trang và bất kể phương pháp nào chúng ta có mọi thứ đi về phía nam theo thời gian. Tôi đang nỗ lực để nâng cao mức độ nhận thức CSS trong nhóm. SASS lồng với phong cách địa phương và phong cách toàn cầu là đủ để giữ cho dự án sạch sẽ dễ đọc.
Adrian Moisa
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.