CSS methodology: To BEM or not?

Is writing CSS the BEM way a good idea? I've been struggling to figure out whether I should start writing CSS that way because I just haven't been able to get over the fact that BEM naming tends to be long and it is tedious to have to give every single element a class name. I do see its modularity, but I've always thought that I could get that by giving each section a unique class name and write nested CSS from there just like how they write HTML in CSS Zen Garden site. Am I missing something here?

If you don't know what BEM is, take a look at getbem.com for a detailed guideline and sample code. I am not convinced of their claims.

They say I should care because BEM supposedly fixes the two most significant common issues:

1) CSS Inheritance

Their argument seems to be that CSS inheritance is infinite without scope or closure, and BEM can provide some scope by using unique CSS classes per element.

2) CSS Specificity

They argue that developers often find themselves using very long nested CSS selectors or the '!important' keyword to overcome existing specificity in an existing project someone else created. It results in a complicated mess of overlapping and conflicting CSS rules. BEM supposedly tames such situation by keeping CSS specificity to a minimum. They also say that BEM makes CSS code readily portable to a different HTML structure. They further argue that BEM avoids CSS conflicts by using unique contextual class names for every block, element and modifier combination and makes it much easier to maintain the codebase.

I'm not entirely convinced. Doesn't wrapping a module with a class/ID and avoiding abusing IDs and !important in the first place solve these problems?

They say that BEM helps to have fewer things for a browser to evaluate, which supposedly results in rendering a webpage faster. Supposedly, locating a class name is faster than evaluating nested CSS definitions. But, by how much?

Comments (62)

Jason Knight's photo

BEM is the type of nonsense the OOCSS fanboys cream their panties over, and to me it only contributes to bad practices of not leveraging selectors properly. Classes and ID's should be a last resort AFTER you've used up your semantic tags, not your go-to to slop onto everything.

You can TELL the folks who encourage the use of BEM are -- as I oft point out -- unqualified to write HTML or CSS; as evidenced by such gems of ignorance and ineptitude (there are those two words again) as:

<div class="block block--size-big block--shadow-yes">

Classes saying what things look like and not what they ARE? Classes that are redundant to inheriting off the parent? That's both pointless code bloat AND presentational use of classes, a double /FAIL/ at web development.

Hardly a shock that 'getbem" website is itself a bloated wreck using two to three times the HTML necessary to do the flipping job!

Overall it reeks as the same garbage some folks advocate of slopping classes onto everything to avoid using selectors entirely -- one of the DUMBEST pieces of advice and based entirely on a LIE about how selectors slow down the render time.

If your site is well coded, render time should be bupkis, at least compared to handshaking and transfer time. Slopping out two dozen separate stylesheets and two to ten times the markup is going to effect your page loading time a hell of a lot more than "oh noes, you used child selectors four deep!".

Much like the idiocy that are front-end frameworks, OOCSS, SCSS, and all the other hot and trendy media darlings, their claims are 100% bunko, the people creating them seem to have failed to grasp the most basic concepts of HTML and CSS, and in general they're a blight upon web development as a whole. AT BEST they are crutches for the inept, at worst... I lack the words in polite company.

That and to be frank, I do not find it aids in clarity or legibility one iota -- quite the opposite in fact.

Show all replies
Steven Ventimiglia's photo

Creative Technologist & Sr. Front-End Developer

That's why he uses the moniker, @cutcodedown. He recently ripped apart a table I wrote in a sandbox example, reminded me of something important I should have remembered, and sent me back to my desk with a mirror so I can see how stupid I was. Old-school and effective.

Tommy Hodgins's photo

I personally think BEM is overkill, and leads to bloated HTML and CSS. I think the way class names are used doesn't make the best use of CSS features (which can match parts of attribute values, if a value starts with, contains anywhere, contains in a space-separated list, or ends with a value).

Also keep in mind that BEM came around in 2013 (half a decade ago) mostly to deal with the way HTML was written for pre-flexbox, pre-grid layouts. There are better, stronger, more lightweight ways we can build HTML now, which means to a great extent, the problem BEM aims to solve doesn't need to exist as much anymore.

But, I won't say not to use it, or that it's bad. It works, so just take the parts of it that still make sense to the technology, and use the parts that actually give you a boost when you're naming things or writing stylesheets. There's no need to adhere to it strictly or fully, just use it so far as it helps you and no further :D

Marco Alka's photo

I've actively used BEM for a few years now, and it helped me a lot. I think, BEM is a great tool to write lean CSS. However, it might as well be one of the hardest to learn and use correctly. That's why some people are against its usage and others shy away from it. To be honest, I still wouldn't say that I am very good at writing BEM myself One might say that that's one of its flaws: it's hard to name a block and not fall back to creating scopes inside the name.

However, the basic usage of BEM yields great benefits. By looking at a class name, you instantly can deduce, which elements should be affected and where they are probably located, if you know the general site layout - even after years, or on a foreign codebase. You do not need long names to achieve that, either. All you have to do is sit back a bit, move your mind a step away, and think about where the element is located logically (not in your HTML structure, which is what you are probably thinking about at that moment).

Another positive aspect of BEM is that it yields a flat hierarchy. There is not sub-element selector. You can easily leverage and mix it with many other CSS tools. For example you can re-order your classes in an inverse specificity (ITCSS: Inverse Triangle CSS), which means that more specific selectors automatically overwrite inheritance from higher selectors in your HTML structure, which leads to you not having to worry about what will change on the rest of the page (by CSS inheritance), and how to make a style even more important after you already used !important.

Of course, BEM can be mixed with SCSS. You can use SCSS to split up your huge file, you can define your basic design colors, you can create mixins for your transitions and a lot more. Just don't do scoping.

BEM can also be extended by applying namespacing, which adds additional information, for example if the class only affects a single element, or might affect 0..n elements, or should not be touched by anyone, even though it has no selector in CSS, because it is used in a script. Namespacing makes it easy to deduce how changes to a class might affect the whole page.

I highly recommend reading about BEMIT and ITCSS. That's where I learned from, and that's what I made very positive experiences with. The one behind these articles and methods, Harry Roberts, also hosted an AMA here on Hashnode some time ago, you should check it out, too ;)

Show all replies
Jason Knight's photo

The less code you use, the less there is to break

Marco Alka I fail to see why web crapplets would be any different. Less markup and less CSS means less code overall.

... though I don't tend to 'believe' in web applications for most content. There are good usage scenarios -- Google Maps for example -- but in most cases all it does is create fat bloated slow garbage that should NEVER be on the Internet in the first place and inhales upon the proverbial equine of short stature when compared to their desktop counterparts!

It's another "oh noes" -- who wants to download applications? ME? That's who! I don't want the crappy slow web crapplet stuck in a browser frame. If I want an application, I want it native.

Probably part of why I hate the rubbish nearly useless Win8/newer UWP crapplets, being amongst the first things I rip out and replace on modern Windows installs to drag it kicking and screaming back to when things WORKED.

Though there are always exceptions -- most of them are built with node.js or electron meaning you're STILL going to download and install something. See Atom, VS Code, Vivaldi...

That last one's kind of funny, it's a browser that's built as a web application with react. Kind of wish they'd ditch that last part since it makes it harder to mod and it's a complete waste of code for simple stuff in the UI, but overall it's still my browser of choice.

But in other words, applications I still had to download and install -- which is probably why I find them a hundred times more useful than the crap running in a browser. See trash like "Office 365" or Google Docs. Cute toy but useless for anything I would need a office suite for.

But what do I know? I've migrated back to Office 97 since it runs flawlessly under Win10 and Wine -- and is faster, leaner, and more useful than any office suite made after it.

Emil Moe's photo

I thought about using BEM and tried to use it, but I have quietly gone away from it again. As you point out the naming conventions are often very and it leads to a few overhead problems:

  • Hard to remember the correct path name and no IDEs will help you
  • If the structure changes you might have to refactor a lot of CSS
  • Longer class names means more bytes, not much, but it's a margin

Since I'm uing SCSS it makes more sense to try to adapt a namespace OOP pattern to my CSS. Simply if I have a component testimonials that would be:

.testimonials {
  > .testimonial {
    > .title {
      // CSS

If you are consistent doing this and not making an independent .title then this approach works very well in my opinion.

If you want to have a generic class, you can always use BEM here:

.utilitiy__ {
    &title {
      // CSS

But you could also simply call it .title as it would still not be inherited from a .testimonial

Show all replies
Kevin C.'s photo

Re-learning after an 8-year hiatus

Sandeep Panda

I'm not exactly sure what happened here (I just noticed these latest posts) but I hope you guys will work something out. I'm relatively new around here, but I've always thought Jason had some helpful insights, and, quite honestly, I would hate to see him go.

I guess you are referring to some of his strong expressions. I see your point even though I didn't mind them personally. I can see some people might be intimidated or offended. In any case, I think he just cares about this stuff deeply and want to help people navigate through waves of conflicting views, sometimes with a very strong clarity. At least, that's how I take it. Can't speak for other people, though.

Have a good day. :)

Maximilian Berkmann's photo

I once was planning on switching to BEM but after reading on it and seeing the amount HTML/CSS code you'll need to achieve things that can be done without bloating both your HTML pages and CSS sheets especially when it doesn't take the cascading part of CSS as an advantage; I never tried it since.

@cutcodedown hits the nail on the head regarding BEM.

CSS variants like SCSS help in building proper CSS without having the drawbacks of CSS with variables and such.

Show all replies
Maximilian Berkmann's photo

@Dan W. He's wrong regarding CSS frameworks yet has a valid point regarding BEM.

Steven Ventimiglia's photo

BEM is a waste of time, imo. It takes longer to learn what NOT to do when you "BEM the rules" than it would just to do it in a dev-friendly, DRY manner. It seems to encourage folks to ignore the "Cascading" in CSS way too often - which is like trying to use nothing but an open flame, and your hands, to cook an egg.

Also, if you're having a hard time evaluating any type of code, you may need to blame the person who wrote it.

Show all replies
Steven Ventimiglia's photo

Creative Technologist & Sr. Front-End Developer

Be explicit, not implicit. Avoid @extend.