(Update 2018: this stuff is still relevant if you’re not writing CSS-in-JS.)
The two base concepts of CSS? Inheritance and specificity.
Apart from the benefits: what’s so bad about it? Well, CSS’ inheritance is infinite. There’s no function scope or closure like in programming. Styles you fill in on top will flow down and will never reach a bottom. When you write CSS, there is always context and you’re about to touch it!
What’s so bad about specificity? You need to become more specific to win over existent specificity. It’s
!important to be clear on this feature.
Today’s web development is driven by the purpose of modularity: chop projects into pieces to make it manageable. We build upon APIs, allow for separation of concerns and keep stuff simple and stupid.
Of course we are willing to write modular CSS, too. But its base features inheritance and specificity do not play nice with modular concepts. Think of modules containing modules containing modules… — Inheritance is hard to handle (at least for humans!) and we’re missing scope.
Web Components will hopefully provide some CSS scope (see Shadow DOM). But while waiting for Web Components to get finished and implemented in common browsers, we’d better use some proper workarounds like:
Why use BEM? Because it tries to get the best out of today’s CSS concerning modularity:
- Avoids inheritance and provides some sort of scope by using unique CSS classes per element (like
- Reduces style conflicts by keeping CSS specificity to a minimum level.
That is what BEM is all about.
#BEM is all about low level CSS specificity and sort of scope by means of unique CSS classes per element. http://t.co/jEa9JcemcE #b_— DECAF (@_DECAF) 25. Juni 2015
— But wait!
My HTML looks all bloated and messy with BEM!
This seems to be the most frequently mentioned argument against BEM.
Remember, until CSS supports scope, there is no way to get around inheritance in modular environments other than sticking unique CSS classes (or attributes) to any given element. Whenever you apply styles by element type selectors (like
li) or generic classes (like
.active) you apply styles not only to the element itself but to a whole cascading context. Even if the context doesn’t exist yet, it may be expanded until someone adds another module or component to your HTML.
— Think of modularity as any module may contain further modules!
So, bloated HTML with BEM? Y’d better call it functional!
And it will be gzipped anyway.
Why not use element type selectors with child or sibling combinators (like
ul > li + li) to avoid inheritance issues?
Nested selectors raise CSS specificity. You need to become more specific to win over existent specificity. Modular contexts require low specificity!
(Furthermore, your CSS would be sort of tight coupled with the HTML. Better get loose coupled and apply styles by unique CSS classes not element structure.)
Nesting is such a brilliant feature of pre-processors! With BEM it sucks.
With BEM any element (more precisely: any group of elements of the same type) can be selected by its unique class. You don’t need selector nesting, even in pre-processors.
That said, Sass 3.3 supports BEM-style nesting!
We’d love to get your feedback on twitter: @_DECAF.
And did you know: hashtag for BEM is #b_.