27

A colleague of mine is heavily pushing the BEM (Block Element Modifier) method for the CSS in a project he's helming, and I just cannot comprehend what makes it better than the LESS CSS we've been writing for years.

He claims "higher performance", but I can't imagine how performance could even matter for the kinds of web apps we write in this code shop. We're not making Twitter or Facebook, here. I'd be very surprised if our highest use apps have more than 10000 hits a month, and most are well under 1000.

He claims "readability" and "re-use", but LESS already does that much better, in my opinion. And I feel that BEM mangles the markup so badly with dozens of extra characters dedicated to these super-long class names that it radically reduces readability.

He claims "nested CSS is an anti-pattern." What does "anti-pattern" even mean, and why is nested CSS bad?

He claims that "everyone is moving toward using BEM, so we should too." My counter is "If everyone was jumping off a bridge, would you follow?" But he's still totally adamant about this.

Could someone please explain in detail what makes BEM better than LESS? My colleague is completely failing to convince me, but I don't know if I have a choice but to follow. I'd really rather be able to appreciate BEM, than to grudgingly accept it.

  • 1
    BEM and LESS serve different purposes. I use both BEM and LESS. – zzzzBov Apr 15 '15 at 18:19
  • 4
    Note that BEM is not primarily about CSS – it's about identifying recurring encapsulated patterns in your design, and gathering everything needed for that block (behaviour, template, styles) in one central place. Even if restricted to CSS only, BEM is still a great way to organize your styles and reliably prevent name clashes. That's all totally independent from preprocessors such as LESS or SASS, which are just more productive styling languages than plain CSS because they offer macros and variables and shorthand notation and all kinds of nice features. LESS=win, BEM=win, but LESS×BEM=win²! – amon Apr 15 '15 at 19:23
29

A colleague of mine is heavily pushing the BEM (Block Element Modifier) method for the CSS in a project he's helming, and I just cannot comprehend what makes it better than the LESS CSS we've been writing for years.

BEM is a CSS methodology. Others include OOCSS and SMACSS. These methodologies are used to write modular, extensible, reusable code that performs well at scale.

LESS is a CSS preprocessor. Others include Sass and Stylus. These preprocessors are used to convert their respective sources into expanded CSS.

BEM and LESS are not comparable as being "better" than one another, they are tools that serve different purposes. You wouldn't say that a screwdriver is better than a hammer, except when considering utility to solve a specific problem.

He claims "higher performance"...

Performance would need to be measured between a classical CSS style of:

.widget .header

and BEM style of:

.widget__header

but generally speaking, CSS selector performance is not a bottleneck, and does not need to be optimized.

BEM "performance" is usually with regard to a developer's performance writing code. If the BEM methodology is used consistently and correctly, it is easy for groups of developers to simultaneously author distinct modules without style collisions.

He claims "readability" and "re-use"...

I don't know that I would tell a new developer that BEM is more readable. I can say that it provides some well-defined guidelines as to the meaning and structure of classes.

Seeing a class like

.foo--bar__baz

Tells me that there is a foo block that is in the bar state, and contains a baz element.

I would absolutely say that BEM is more reusable than a classical model.

If two developers create blocks (foo and bar), and both of those blocks have headings, they can safely reuse their blocks in different contexts without worry of a naming collision.

That's because, in a classical context, .foo .heading and .bar .heading would conflict, and introduce a specificity conflict that would need to be resolved, possibly on a case-by-case basis.

In a BEM site, the classes would be .foo__heading and .bar__heading, which would never conflict.

He claims "nested CSS is an anti-pattern." What does "anti-pattern" even mean, and why is nested CSS bad?

An "anti-pattern" is a coding pattern that's easier for inexperienced developers to learn and use than a more appropriate alternative.

As far as why nested CSS is bad: Nesting increases a selector's specificity. The higher the specificity, the more effort it takes to override. Inexperienced developers often worry that their CSS might affect multiple pages, so they use selectors like:

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

When an experienced developer would worry that their CSS might not affect multiple pages, so they use selectors like:

.more

He claims that "everyone is moving toward using BEM, so we should too."...

That is a bandwagon fallacy, so ignore that as a bad argument. Don't fall trap to the fallacy fallacy, because a bad argument in support of BEM isn't a reason to believe that BEM can't be good.

Could someone please explain in detail what makes BEM better than LESS?

I covered this before, BEM & LESS are not comparable. Apples and oranges, etc.

My colleague is completely failing to convince me, but I don't know if I have a choice but to follow.

I recommend taking a look at OOCSS, SMACSS, and BEM, and weighing the pros and cons of each methodology...as a team. I use BEM because I like its strictness in format, and don't mind the ugly selectors, but I can't tell you what's right for you or for your team. Don't let one outspoken individual run the show. If you're not comfortable with BEM, be aware that there are other alternatives that might be easier for your team to support. You may need to defend your position with your coworker, but long-term it will likely have a positive effect on the outcome of your projects.

I'd really rather be able to appreciate BEM, than to grudgingly accept it.

I wrote an answer on StackOverflow that describes how BEM works. The important thing to understand is that your ideal selectors should have a specificity of 0-0-1-0 so that they are easy to override and extend.

Choosing to use BEM doesn't mean you need to give up LESS! You can still use variables, you can still use @imports, and you can certainly continue to use nesting. The difference is you want the rendered output to become a single class, rather than a descendant chain.

Where you might have had

.widget {
    .heading {
        ...
    }
}

With BEM you can use:

.widget {
    &__heading {
        ...
    }
}

Additionally, because BEM revolves around individual blocks, you can easily separate code into separate files. widget.less would contain styles for the .widget block, while component.less would contain styles for the .component block. This makes it much easier to find the source for any particular class, although you may still wish to be using source maps.

  • 4
    @CoreDumpError, the problem is when you start nesting modules within modules. "each developer can just nest their specific widget's code one level deeper" is not quite correct, each developer must nest their specific widget's code deeper and deeper otherwise naming collisions cascade in ways that are generally unintentional. The only way to avoid naming collisions is with some sort of namespacing, and BEM offers an easy way to consistently namespace classes. – zzzzBov Apr 15 '15 at 23:53
  • 3
    @CoreDumpError, Consider this example. An author writing without BEM needs to spend additional effort to verify every combination of every module that might be added within their module. An author using BEM doesn't. – zzzzBov Apr 16 '15 at 0:07
  • 1
    @CoreDumpError, it certainly might be. I find BEM easy to train new developers in and it makes it easy to code review, but SMACSS and OOCSS are good alternatives. I highly recommend looking into those options as an alternative. I will say that I use BEM for my own development so that I don't conflict with myself, especially with future me, who is stupid and forgets things. – zzzzBov Apr 16 '15 at 17:08
  • 1
    I find BEM is excellent on any project that involves any sort of complexity is css. You can have a site that sits on WordPress and only uses Javascript to trigger things on scroll, but is still as complex as a web app in the css. It's important not to fall into the trap of thinking 'my site isn't complex' just because it does most of it's stuff purely in the visual realm (like lots of marketing sites do) – Toni Leigh Oct 15 '15 at 21:27
  • 1
    @CoreDumpError most of my previous projects have been solo endeavors, and I arrived at much of BEM on my own re: specificity and unique selectors. Maintaining a codebase is a huge problem that becomes extremely clear with BEM. Code is maintenance. Building things is easy. Retaining perfect patterns is hard, especially after a few months away from the codebase. Specificity problems compound over time. The benefits apply to any size team IMO! – Yuji Tomita Sep 2 '16 at 4:26
8

Edit 2017

If you're reading this in 2017, the shadow DOM and shadow DOM polyfills, plus components solve all of these problems, while keeping your code small, tight and modular. Don't use BEM on a greenfield project IMO.

Instead of BEM, we have tools like ViewEncapsulation, Polymer, StyledJSX, SASS Modules, Styled Components, etc.

Consider using BEM if you don't have a component-oriented architecture; if you have legacy code to support; or if you are just dead set on doing everything manually without tooling.


BEM makes your styling independent of your DOM nesting. It does this by giving every element you might want to style a big-ass class attribute that is likely to be unique on your page. Most styling is then done on classes.

This makes your code more modular, because nesting is no longer taken into account, at the expense of a great deal of verbosity.

Without BEM

Without BEM, we might write this:

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

Standard CSS styling might look like this:

.widget {
  border: 1px solid red;
}

.widget a {
  color: green;
}

The same thing with SASS would look like this:

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

If you're a small team where everyone can code CSS to a high standard, and the project is small enough that you can maintain full cognizance of it, this is a good and reasonable solution.

With BEM

However, if your code becomes larger, and you have a large mixed ability team, this might not be such a simple solution. What if you want green anchors in another widget for example. So we make the anchor modular, and eliminate descendant selectors.

Now our HTML is much more verbose:

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

Our CSS has no descendant selectors:

.widget {
  border: 1px solid red;
}

.widget__anchor {
  color: green;
}

But we can now do this:

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

The widget__anchor is modular. It's unlikely that another definition of .widget__anchor will exist on the page.

tradeoffs:

BEM:

  • Gives you more modular code. You can take any piece in isolation.
  • Lets anyone write CSS. You don't need to be aware of master styling, and custom overrides. In a large team, this is nice.
  • Removes any specificity issues.
  • Is significantly more verbose.

Standard CSS (which relies on the use of descendant selectors):

  • Means your styling is dependent on context.
  • Requires an awareness of the cascade. Code in once place can affect code elsewhere. In a small team this is a good thing.
  • Can suffer from specificity issues that might be hard for a novice developer to debug.
  • Is significantly tighter.

The third way - Real Components.

If you are using something like React, Angular 2, or any of the other modern front-end framewords, you have another solution. You can use tooling to enforce encapsulation.

This example uses React and StyledJSX, but there are many options. Here's a widget:

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

You would then make use of the new widget like this:

<Widget />

All styles declared in widget would be encapsulated, and would not apply to elements outside the component. We are free to simply style the div and the a directly without worrying about accidentally styling anything else on the page.

  • 1
    Pros and Cons without favoring any side, I like it. – Adrian Moisa Feb 18 '17 at 11:22
  • I think there's something really sad about saying "write your code like this so that people who don't understand cascading can understand it". It's like saying "I write my code without any arrays because one of the junior members of the team doesn't understand how arrays work". Personally I prefer the more succinct method that favours the natural cascading side of cascading style sheets. – Matt Fletcher Apr 24 at 9:15
  • @MattFletcher - I think it's a matter of project size. The cascade is inherently global. You set values, then override and override down through the tree. If you have a smaller project with full visibility this is fine, but on a larger project, it becomes brittle. People become afraid to change things because a change higher up the cascade breaks random things in other places. Component encapsulation is actually really nice on larger projects. Everything just works. – superluminary Apr 26 at 11:52
2

No approach is perfect. IMHO, we should get the best parts of each of the methodologies( BEM, SMACSS, OOCSS, DRY). Use SMACSS for organizing your folder structure in your CSS- specially for defining logical level breakdown of the whole CSS. DRY to to create your utility library or may be common modifier library to be used sometimes in conjunction with BEM based classes. OOCSS for components. And BEM for small components or sub-components. There by you can distribute the complexity, and get freedom to work inside a big team.

Anything when used without understanding the essence of it will result bad.

While BEM is good approach for larger teams, it has some downsides as well. 1.It sometimes result in very long names in large HTML structure. Resulting large CSS file size. 2. For nesting htmls that is more than 2-3 levels, it becomes a headache to define names.

Conflict resolution can be easily managed if we think of component structure along with a very basic set of base style. It's more of a two level inheritance only. Every element inside a component would either have a global style rule or specific to that component. This is one of the easier options.

  • Extremely good argument. Developers should be able to think for themselves and analyze the scope of the problem. Just blindly following methodologies still leads you to trouble. I have colleagues who do not consider the effects of their changes on the page at all and no matter what methodology we have things go south in time. I'm pushing hard to raise the CSS awareness level in the team. Nested SASS with local styles and global styles is enough to keep the project clean is easy to read. – Adrian Moisa Feb 18 '17 at 11:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.