The following is a collaborative post by guest Joe Richardson, Robin Rendle, and a bunch of the CSS-Tricks staff. Joe wanted to do a post about BEM, which we loved, and just about everybody around here had thoughts and opinions about BEM, so we figured we’d all get together on it and do it together.
The Block, Element, Modifier methodology (commonly referred to as BEM) is a popular naming convention for classes in HTML and CSS. Developed by the team at Yandex, its goal is to help developers better understand the relationship between the HTML and CSS in a given project.
Here’s an example of what a CSS developer writing in the BEM style might write:
/* Block component */
.btn {}
/* Element that depends upon the block */
.btn__price {}
/* Modifier that changes the style of the block */
.btn--orange {}
.btn--big {}
In this CSS methodology a block is a top-level abstraction of a new component, for example a button: .btn { }
. This block should be thought of as a parent. Child items, or elements, can be placed inside and these are denoted by two underscores following the name of the block like .btn__price { }
. Finally, modifiers can manipulate the block so that we can theme or style that particular component without inflicting changes on a completely unrelated module. This is done by appending two hyphens to the name of the block just like btn--orange
.
The markup might then look like this:
<a class="btn btn--big btn--orange" href="https://css-tricks.com">
<span class="btn__price">$9.99</span>
<span class="btn__text">Subscribe</span>
</a>
If another developer wrote this markup, and we weren’t familiar with the CSS, we should still have a good idea of which classes are responsible for what and how they depend on one another. Developers can then build their own components and modify the existing block to their heart’s content. Without writing much CSS, developers are potentially capable of creating many different combinations of buttons simply by changing a class in the markup:
See the Pen BEM example by CSS-Tricks (@css-tricks) on CodePen.
At first this syntax might seem slower than simply making a new class for each type of button, but this is not the case for several reasons we’ll cover.
Why should we consider BEM?
- If we want to make a new style of a component, we can easily see which modifiers and children already exist. We might even realize we don’t need to write any CSS in the first place because there is a pre-existing modifier that does what we need.
- If we are reading the markup instead of CSS, we should be able to quickly get an idea of which element depends on another (in the previous example we can see that
.btn__price
depends on.btn
, even if we don’t know what that does just yet.) - Designers and developers can consistently name components for easier communication between team members. In other words, BEM gives everyone on a project a declarative syntax that they can share so that they’re on the same page.
Harry Roberts identified another key benefit of using a syntax like BEM when he writes about improving developer confidence:
This is the main reason we end up with bloated code bases, full of legacy and unknown CSS that we daren’t touch. We lack the confidence to be able to work with and modify existing styles because we fear the consequences of CSS’ globally operating and leaky nature. Almost all problems with CSS at scale boil down to confidence (or lack thereof): People don’t know what things do any more. People daren’t make changes because they don’t know how far reaching the effects will be.
Likewise, Philip Walton argues that this problem can be fixed if enough developers stick to the principles of BEM:
While 100% predictable code may never be possible, it’s important to understand the trade-offs you make with the conventions you choose. If you follow strict BEM conventions, you will be able to update and add to your CSS in the future with the full confidence that your changes will not have side effects.
So if developers can work on a project more confidently, then they’re sure to make smarter decisions about how these visual components should be used. This methodology might not be a perfect cure for all these ailments, but it certainly gives developers a standard on which to write better, more maintainable code in the future.
Another smart part of BEM is that everything is a class and nothing is nested. That makes CSS specificity very flat and low, which is a good idea. It means you won’t end up fighting with yourself over specificity.
Let’s take a look at some of the problems with BEM…
BEM CSS
Problems with Of course nobody will twist your arm if you break from BEM rules. You could still write a CSS selector like this:
.nav .nav__listItem .btn--orange {
background-color: green;
}
That looks like it has parts of BEM going on, but it’s not BEM. It has nested selectors, and the modifier doesn’t even accurately describe what’s going on. If we did this, we’d be screwing up the specificity flatness that is so helpful with BEM.
A block (such as .nav
) should never override the styles of another block or modifier (such as .btn--orange
). Otherwise this would make it almost impossible to read the HTML and understand what this component does; in the process we’re bound to greatly shake another developer’s confidence in the codebase. This goes for HTML, as well: what would you expect if you saw the following markup?
<a class="btn" href="https://css-tricks.com">
<div class="nav__listItem">Item one</div>
<div class="nav__listItem">Item two</div>
</a>
What’s probably going on here is that an element in a completely unrelated block has the code a developer needed, but the child elements don’t require a .nav
class as the parent. This makes for an exceptionally confusing and inconsistent codebase which should be avoided at all costs. So we can summarize these problems by:
- Never overriding modifiers in an unrelated block.
- Avoiding making unnecessary parent elements when the child can exist quite happily by itself.
More examples of BEM in action
Accordion demo
See the Pen BEM Accordion by CSS-Tricks (@css-tricks) on CodePen.
In this example there is one block, two elements and one modifier. Here we’ve can created an .accordion__copy–open
modifier which lets us know we shouldn’t use it on another block or element.
Navigation demo
See the Pen BEM Menu by CSS-Tricks (@css-tricks) on CodePen.
This navigation demo has 1 block, 6 elements and 1 modifier. It’s even perfectly OK to create blocks without modifiers at all. At some point in the future a developer can always bolt on (or bind to) new modifiers so long as the block remains consistent.
Dislikes of BEM
Perhaps you don’t like the double-underscores or double-dashes thing. Fine, use something else that is unique that you will consistently enforce.
Here’s another sentiment:
Not sure I'm sold on BEM.
.site-search
.site-search__field
.site-search–full
Why not:
.site-search
.site-search input
.site-search .full
— Samuel Fine (@samuelfine) March 11, 2015
Those last three selectors all have different specificity levels. They either require parents or not. Without any rules in place, they don’t say as much as the ones on top.
Is it possible that this tiny, isolated example feels perfectly fine to you and never ends up biting you in the butt? Perhaps. But the more CSS you have in a project, the more little things like this add up, the more specificity and complexity battles you go through.
BEM sounds super useful if you don't know how HTML or CSS work.
— Samuel Fine (@samuelfine) March 11, 2015
Not to pick on Samuel here, but his sentiments are shared by a lot of people so it makes for a good example. They see BEM, and they just outright reject it. If you want to dislike BEM, that’s absolutely fine, but I think it would be hard to argue that having a set of rules that aid in understanding and assist in keeping CSS maintainable is a bad idea.
In the SMACSS methodology, you’re likely to find a CSS classname with three letters. Modifiers then follow the module name with a hyphen:
/* Example Module */
.btn { }
/* Modifier of the btn class */
.btn-primary { }
/* Btn Module with State */
.btn.is-collapsed { }
That’s just a different naming approach to the same kind of problem. It’s pretty similar, but you’re just being more specific about dependencies and keeping specificity flatter.
In OOCSS, blocks are similarly generic.
/* Example Module */
.mod { }
/* Part of Module */
.inner { }
/* Talk Module */
.talk { }
/* Variation of part inside Module */
.talk .inner { }
So you would use multiple classes in the HTML for variations. The inside part isn’t named like it has a dependency, so it is less clear but potentially more reusable. BEM would do .mod__inner
and .mod--talk
and .mod--talk__inner
.
These are just variations on methodology. Remember that nobody is twisting your arm here, these are self-imposed rules where the value comes from following them.
Sass and BEM
For those of you writing Sass and enjoy nesting as a way of scoping styles, you can still author in a nested format, but get CSS that isn’t nested, with @at-root
:
.block {
@at-root #{&}__element {
}
@at-root #{&}--modifier {
}
}
Gets you:
.block {
}
.block__element {
}
.block--modifier {
}
And you can get as abstract as you want! Check out Danield Guillan’s BEM Constructor or Anders Schmidt Hansen’s Expressive BEM.
Summary
To wrap things up I think it’s fair to say that even though BEM won’t solve all our problems it is extraordinarily useful for constructing scalable and maintainable interfaces where everyone on the team should have a clear idea of how things can be improved. This is because a great deal of front end development is not just about the nice tricks that solve one little problem in the short term; we need agreements, promises and binding social contracts between developers so that our codebase can adapt over time.
Generally I like to think of BEM as an answer to Nicolas Gallagher’s question:
Replace "can you build this?" with "can you maintain this without losing your minds?"
— Nicolas Gallagher (@necolas) July 24, 2013
I’m with Samuel on this one, I don’t like it.
I understand the pros and cons, but for me the cons outweigh the pros.
Sometimes we’ll add a prefix to a class name so the relationship between things is obvious, i.e:
.form
.form-fieldset
.form-text
instead of
.form
.form fieldset
.form input[type=text]
But that’s as far as we take it. This idea behind dashes and underscores is kind of messy and confusing to me.
Yeah, the dashes and underscores look wierd
For me, it seems to make it much easier to look at one element and tell where all (or at least a good solid chunk) of its styling is coming from.
In the
.form-fieldset
example above, what if I want a specializedfieldset
in aform
that’s green? Now I have.form-fieldset-green
–is this a greenfieldset
inside aform
or is a green class on an element inside thefieldset
inside theform
?To me that distinction between elements through the
__
and modifiers through--
works wonders. Now I know that.form__fieldset--green
is green fieldset inside aform
at quick glance.Agreed, let’s not go back to 2006 and have ourselves some huge bowls of class soup
A while ago I stumbled upon this: https://github.com/rstacruz/rscss. Started using it and in my opinion its clearer then lots of underscores etc. And code looks cleaner too.
Re-factoring is easier when using BEM. Without dashes and underscores, I bet you will HAVE to use nesting and with nesting you will run into cascading overwrites and uncertainty when you need to rename or remove classes. You also will not be able to reuse nested class that easily in a new place and you will have to re-factor again.
Here you can find more details on the topic with example.
I am a big fan of BEM.I am using BEM for all my office and personal projects from last two years.BEM never been a pain in the ass, especially when you work on large projects and large teams. the html looks clean, readable and easily understandable. helps in creating a perfect modularization for style sheets. Helps and tends you to write or develop more modular codes. with the help of sass or less you can make website authoring to a kickass experience.
Most of my friends complained about the underscore and long names which look’s weird, need to type more, lot of bullshit blah blah. but the main benefit I see from my experience
Understanble HTML document
Helps you in writing modular stylesheet
Easy stylesheet maintenance
BEM make you think webpage as composition of components
which helps in creating reusable stylesheets
BEM improves readability in javascript code while dealing with class names.
My biggest benefit that I got from BEM is, it trained me a lot to thinking in modular way. not only css,but also in programming. I can feel the change and the advantages that i gained.I don’t how to explain it, yeah.. its true.
Give it a try.
Peace
SCSS and BEM works for me, I would normally write something like:
Question:
What if you have…
…and need to CTRL+F for .block__title? Wouldn’t it make more sense for all classes to be easily searchable? Nesting looks cleaner, but I think there’s a definite drawback in not being able to CTRL+F for something inside the codebase.
BEM (and other component methodologies) promote a one-component-per-file approach. So finding stuff begins with opening the file for that component (Ctrl-P or Ctrl-T or whatever Navigate-to-File shortcut your editor has). This is great because it immediately reduces the scope of your search. If the file is too big to visually scan, you simply Ctrl-F for &__title.
@Jeremy – @Mike summed it up pretty well. Being that the block has been named correctly and your file structure is logical you won’t struggle to find what you need. I had the same worry before but haven’t looked back since. Choose a file structure that suits you and the project best, and use CTRL + SHIFT + F in Sublime to find a class quickly across multiple .scss files. Maps can help too.
Thanks guys. That makes sense.
The lates Sass version supports BEM in the following way:
Which would result in
You can see it online here – http://sassmeister.com/gist/fe753a8228da9ed45136
The same syntax would work for LESS as well. In case any LESS users were curious.
There is no need in
@at-root #{&}__element
, because&__element
is also working in sass.I didn’t like the verbose look of BEM at first but it’s amazing how quickly I got over it. It’s easier for me to understand structure now glancing at BEM CSS and it helps coming up with naming too.
Personnaly I love this : https://github.com/rstacruz/rscss
it put a little bit deepness into selector but it correct something that bother me with bem : the length of the class title.
I don’t know in what mesure confortable selector is important with deepness, but I do prefer it.
I’ve been using BEM on my last few projects and I think it works well. The only thing I’ve done differently is switch up the underscores and dashes since I prefer dashes and my CSS usually contains more elements than modifiers.
I love BEM. At first I shyed away from it because it’s so ugly but then I realised I can use mixins to abstract the formatting in css. In scss it’s more characters than it’s worth but with indented sass it’s kind of beautiful
gracefully compiles into
Here are the mixins for those wandering
I like this method. Thanks, Charlotte.
Hi guys, what do you think about following library which takes similar approach?
https://github.com/danielguillan/bem-constructor
This looks great! Thanks Charlotte :)
That looks great, thanks!
even i also don’t like this… may be we can go for camel case pattern.
.btn {}
/* Element that depends upon the block */
.btnPrice {}
It will be help full to maintain the code pattern in js also….
Sass + BEM is a great reason to use BEM. Both seem to be meant for writing CSS that you DON’T GET CONFUSED BY.
I guess my BEM is more just .parent-child and I use few modifiers, if ever. I have taken to writing high level layout blocks with a
l_
prefix like:BEM would be more like
.l_header__nav
, but I use dashes simply because if I want to select any element of the selector, dashes are better for double-clicking in text editors. (Underscores are word-characters so double-clicking will select the whole selector.) May be a weird reason to do that, but it helps my workflow.I’ll chime in as, for my sins, I find CSS architecture eternally fascinating.
IMHO any approach that attempts to rationlise and enforce HTML classes and CSS selectors is better than no system. The more complicated the system/UI, the truer this becomes.
You can dislike BEM syntax (I’m not a fan) but the principles buy you far more than using no system at all (particularly at scale).
I also dislike the practice in Sass of using the parent selector to nest; you lose the one to one relationship with your markup (you can’t select a HTML class from Dev tools and search for the selector in a Sass codebase).
For very large complex UIs (and depending upon how you are building them) I have found different approaches more advantageous (I call my own Enduring CSS) than BEM, principally the use of a micro-namespace as a means of containment. I have found this in practice to be more robust, faster to iterate on, more understandable from a naming POV (that last point is entirely subjective though).
Whatever, you choose, however you adapt from what you begin with, to have some approach is infinitely better place to be than no defined approach at all!
Hey Ben, if you structure your Sass files so that each block gets its own folder and its own
scss
file, then searching by a selector becomes no longer necessary as looking at.footer__copyright
will lead you to thefooter
folder at once without any searches, then it’s only a matter of finding__copyright
in that particular file :)“you can’t select a HTML class from Dev tools and search for the selector in a Sass codebase).”
Use sourcemaps instead….
@Alex I’m using Sublime at present, I can double-click an HTML class in the DOM, CMD+C and then in Sublime CMD+R and CMD+V to find that Symbol project wide. Within a second it takes me straight to that selector in my Sass/CSS ready to type. I find that infinitely quicker than manually browsing for a component folder (I have in excess of 100 components).
@ewfwefewfewewf – souremaps mean I need to edit in the browser. I prefer to edit in my text editor.
OFFTOPIC–
@Ben Frain
Although you can edit in the browser (Chrome) and save the file , that’s a browser feature rather than a source maps feature.
How I edit in my text editor and use source maps:
Enable source maps (Chrome).
View the line a specific rule is located in the source/preprocessed file.
Edit.
If you use Sublime Text you don’t have to “find” that rule, just press
CTRL+G
(Windows) and type the line number.To clarify your point about SMACSS, if
.callout
is a variant of.module
, it should be named.module-callout
.There is very little difference between BEM and SMACSS. In SMACSS, it talks of modules, sub-modules, and sub-components. These map directly to blocks, modifiers, and elements.
Is there a single developer here who has actually used BEM on a project and not bought into it? its easy to dismiss it because it ‘looks funny’ or you ‘dont like the __ or –‘ but thats just left over thinking from the ‘best practices’ which we already know are not necessarily best at all. The bigger the project and the more people contributing to it – the bigger the benefits of something like BEM.
As for Sam’s tweet, would you honestly feel comfortable joining a project and changing the .full rule? I highly doubt it, which will lead to higher specificity selectors and as the project grows – less consistency/maintainability. (which wastes time & money and doesn’t look good)
Give it a try, you might be surprised.
Exactly, once you forgo any initial concerns and actually start using this approach on a project it’s amazing how useful it becomes, and how strange not using it seems.
I challenge any naysayers to give it a go on a project, I think you’ll be surprised at how it changes the way you see your CSS. It’s almost indispensable once you get your head around it.
This. After couple of projects with BEM (and SASS) I realized that there had been significantly less issues with classnames and conflicts. It’s just one of those things that kind of silently grew on me.
One think I like about it is that I can safely use generic words (block, area, container) as BEM -element names. It really speeds up the development when I don’t have to think new names that much.
And, like many have said here, the @at-root can be removed with new SASS version. Like this:
Great write up on BEM. I see that there are mixed opinions on it whicvh is great and reflects the expressiveness of css.
I find BEM to be both scalable and readable (which is why we use it). At first we used it purely to identify parent-child relationships and I struggled to find a use for modifiers at all but the more we used it the more we realised that used correctly you can build extremely flexible and lean architecture!
If anyone is interested I wrote a little WordPress script to create dynamic BEM menus and (if you like BEM) I’m sure you will appreciate how much easier it is to create complicated multi level navigation with BEM syntax rather than
.menu-name li > ul > li{}
.If you have never used BEM before it serves as a practical usage example:
https://github.com/roikles/Wordpress-Bem-Menu
Too verbose, and looking too weird. Intermixing underscores with double dashes with single dashes with camelCaps. No thank you sir. Just using single dashes for inheritance AND sublevel elements works absolutely fine, doesn’t look weird or verbose, and doesn’t invite to write selectors that are too specific.
Thanks for a great article Joe, Robin and the bunch.
In my experience it depends a lot on the complexity of a given project, personal preference (my mental model) and the team I’m in.
Some projects are too small (not very complex) to make sense using a BEM-ish approach, while other projects that require high modularization have, in my experience, benefited greatly from BEM.
In the case of the startup team I’m a part of, it just makes it easier to discuss and understand our code when things are very component-based and follows BEM. Well, the “Roberts meets Gallagher meets Snook meets our own blend” version of BEM, that is.
For us, we need things to be very much like LEGOs – able to move around independently, be removed or added easily – since we need to iterate quickly based on customer feedback and user testing results. BEM helps us a lot with that.
Truth be told, when I first saw BEM I was not very convinced, but after trying it out I began to really enjoy it. Maybe it’s like React’s “give it five minutes”.
All of the benefits of BEM make sense to me and I like it. My biggest complaint with it is the classnames get really really long. Especially the deeper you get in the module.
For instance assume the following HTML/CSS:
.accordion
.accordion__title
.accordion__title__icon
And then let’s say I want a modifier on .accordion__title__icon –
class=”accordion__title__icon accordion__title__icon–facebook”
I realize that we could shorten the name of the class, but that sort of defeats the purpose of making everything easy for other developers to quickly understand what’s going on.
With BEM you should probably avoid using code like “accordion__title__icon accordion__title__icon–facebook”.
You’d be better off making ‘accordion’ and ‘icon’ as separate components. Then just combining them.
This has the advantage of each is useable elsewhere in your site without needing the other. The goal is to abstract each piece so it can be used independently elsewhere.
Hey Neal, I agree with @Andrew H here in that you usually don’t need to nest so deep. If you have an element inside of an element then the top-most element can probably be a separate block. I once wrote an article about BEM mixins, if you are interested, please take a look.
I agree with guys above. However I don’t like that pattern of specifying base class together with modifier class, it is really redundant (
class=”accordion__title__icon accordion__title__icon–facebook”
).Here you can learn about a simple workaround.
I’m fine with enforcing consistency and having a naming convention but the dual underscores looks horrible, especially when combined with single/double hyphens.
It’s an oft-repeated misconception that BEM specifically requires double underscores or dashes. That’s their default recommendation, in order to support hyphen-separated names, e.g.
.menu-button__submit-icon
. But it’s valid to adopt a Pascal-cased approach e.g..menuButton_submitIcon
. See the examples in their docs.I suggest you read ‘Modern CSS Architecture and Front-End Development’ by Harry Roberts from the Smashing Book #4.
If you like the concepts of BEM but not the syntax, there are other options, like SUIT: https://github.com/suitcss/suit/blob/master/doc/naming-conventions.md
I take things one further. I use namespaces in my CSS.
Harry shows some of the benefits of it here: (has Harry ever done a guest blog here? He should. Try to get him to. )
http://csswizardry.com/2015/03/more-transparent-ui-code-with-namespaces/
I only make one amendment. I use ‘.namespace-block-element–modifier’ because underscores are to easy to miss.
Seems like the first “C” in CSS is the most dreaded thing… :-)
Rightfully so, since you can’t stop the cascade.
For those of you who don’t like to write long CSS class names. Stop doing it by hand, try BH template engine for this: http://bem.github.io/bh/
This template code:
applied to this json:
will give you this html:
for the love of god i hope this doesn’t catch on.
its ugly as sin and feels like a time machine to 2004
specificity is NOT your enemy if used correctly
All the comments about how “ugly” the double underscores is seems to be missing the point. Whether or not it’s ugly, BEM is certainly clear what the intentions are. Clarity and structure is the point not how pretty or ugly the markup and CSS is.
@Brendan, I did use it on the project and came to dislike it even more. It is abuse of CSS. One even may venture further and claim that it basically goes against some core principles of CSS.
It may have it’s place, but it is overused already.
First, kudos for trying it before judging it. However, I do strongly disagree that it BEM is abusive, or antithetical, to CSS. Can you expound on this strong viewpoint?
CSS is a vague specification. It’s unique design goals included compactness, device-agnosticism, and shared authority between publisher and user (which turned out to have little long-term importance). Nothing in BEM contradicts these tenets in any way. BEM merely adds “cooperative componentization” to CSS: rules are grouped together logically, and each group respects a common set of strict constraints on selector construction.
Aside from the
ugly__syntax--conventions
(which can be changed) my biggest objection is that you have a chain of class names in your HTML, e. g.class="btn btn--big btn--orange"
This way you have a lot of variations which can be combined freely … but does this help to get a consistent style on your website? If you wouldn’t do classes that are named based on characteristics like size or color, but based on function, maybe suddenly there are considerably fewer meaningful combinations.
And many of them could be done by giving a parent element a reasonable class. Why make the button bigger? Because the user has a touch device? Then give the body the class
.touchDevice
and many more elements can be adapted simultaneously. Yes that creates specificity, but as el generico wrote: It’s not your enemy if used correctly.If possible and not too confusing I try to group my classes in CSS so that I don’t have to define basic things repeatedly. Example:
This way I don’t have to write
class="btn btn-deactivated"
butclass="btn-deactivated"
is enough. What’s in the classname that’s in the style, btn and deactivated.I like my CSS and HTML short and concise. Class chains clearly aren’t my thing.
Yey, finally I found another person with same view on the problem! I’m so happy now :) Please take a look at my article which describes another way to group modifier classes, using attribute selectors. I wonder what you think.
Sergey, the idea to use the CSS selectors
[class^="block--"], [class*=" block--"]
is great. So you can also shorten your class lists in the CSS files.I’ve used something similar on a website that consisted of equivalent slides. With
[class^="slide-"]
I gave the base styles to all slides; while with.slide-1
,.slide-2
,.slide-3
etc. I set individual properties like the background image.Sure, you could write short and concise CSS in BEM methodology.
One approach is to use preprocessors like SASS, so you can define your styleguide explicitly:
You also can use full BEM stack and therefore avoid writing HTML by hand:
Couldn’t we use partial attribute selectors in our CSS too ?
[class*=–disabled]{pointer-events:none;}
Wouldn’t this cover any .block–disabled item.
Fine question. The semantics of “disabled” might mean different things in different logical contexts. If we’re talking about an input field, disabled might mean “this control is read-only”. At the higher levels of abstraction that BEM blocks enable, we might have a listing of Product blocks in our Product Listings block. Such a Product might itself have a “disabled” state, which could mean “this product is unavailable for sale because it’s out of stock”. These two definitions of disabled are different, and will have different presentational implications.
With your suggestion, we ignore and do not permit logical context in our code design. The word “disabled” is assumed to have one common meaning regardless of the context in which it’s applied. Ultimately, that discourages working at higher levels of abstraction because it’s cumbersome and painful to re-define the meaning of class names with the cascade. And without abstraction, we are forced to think about the entire front-end in terms of low-level HTML primitives, which wastes our limited cognitive capacity. In the worst case it exhausts that capacity, making the front-end indecipherable, unpredictable, and prone to regression.
Was hoping the article would address my main gripes with BEM (which I otherwise love), which sometimes make me end up writing crazy long classess like
section-name__content__blurbs__blurb__title
:How do you decide what is a block? Surely the entire page isn’t a single block, but how do you decide how to decompose it?
How do you name elements whose only purpose is to make some CSS hack/feature work? Imagine you have a
hero
element, which to the eye just contains aheadline
and atagline
as ostensible children. You’d love your classes to be.hero
,.hero__headline
, and.hero__tagline
, but you needed a couple intermediate elements to accomplish some design goal (e.g. a wrapper, a pre-flexbox container for vertical centering — use your imagination). Those elements need styles, so are you forced to write.hero__wrapper__container__headline
? Sometimes I do it, but I also think of it as a reductio ad absurdam for the whole convention. Other times I fudge and say “the wrapper element isn’t so much a child of the parent as part of the implementation of the block, so I’ll call it.hero--wrapper
and reduce the length of the child selectors by one.” But this dilutes the naming convention.Namespaces. Need a hack to make code work? Prefix with “_”.
http://csswizardry.com/2015/03/more-transparent-ui-code-with-namespaces/
“How do you decide what is a block?”
Any element that is self-containing and can be decomposed. If you can move this anywhere on the page and have it function exactly how it does anywhere else. That is a block. Navigation, content area, side-bar, footer, header, carousel, etc.
Zack, there’s no reason to mirror nesting structure in element’s name.
Hero
layout could be something like this:Unless you have elements with the same name on different nesting levels (which is not a great idea on its own) you still got a bulletproof protection against css selectors’ collision.
Roman, I’ve never seen a problem to layout in more classic and semantic way:
Therefore, LESS or SCSS code looks something like that:
Clean and simple, isn’t?
This layout could be easily broken by nested block, as block1’s selectors would affect block2 elements.
BEM naming may be not that clean and simple, but it guarantees bulletproof incapsulation.
I’ve forked the first pen to provide a brief example of BEM templating: http://codepen.io/sameoldmadness/pen/yyWXZm?editors=001
It’s upsetting to see a lot of discussion in the comments around “proper” class names.
After all, BEM is not telling you how to name your classes. Instead it is proposing a way to separate your code into atomic reusable components.
Just look at the basic block declaration in BH syntax:
It has nothing to do with html, css or js.
But the block itself could contain logic implemented in all of these technologies (and even more).
For the
.mod--talk__inner
example, I prefer keeping the modifiers on the block whenever possible. So, this would be:Otherwise, you’d need a new modifier class for each element of a block.
I suppose this messes with specificity, but .mod–talk .mod__inner should have precedence anyway.
But, I guess this brings up the question: Should elements be nested inside blocks?
You’re spot on with the first block of code – only nesting them inside a modifier, or as a separate modified class e.g.
.mod__inner--wide {}
The following would be redundant, as
.mod__inner
is named in such a way that we already know it’s an element of.mod
:You’re reducing the amount of fighting you’ll have to do with specificity as components develop.
First of all, I hope you are modularizing your CSS whether you use BEM or not. Secondly, take a look at your current projects. Do you often nest unrelated modules inside of your modules? If that’s the case then use the BEM approach. If not, use an approach that makes the HTML and CSS more readable.
I wrote Title CSS as a way to easily locate module classes and create a scope for short descendant classes. https://github.com/cuth/Title-CSS
I find that using “orange” as a class name in the example is really a bad idea.
Because, of course you’ll have someone write a
.sidebar .orange { color: blue; }
, BEM or not.Why not use
.primary
or.secondary
?Here is a good blogger explaining semantic css.
I often get the feedback from the backend guys that using BEM creates much more work for them and the project manager doesn’t like to hear that. Their argument is that it is easier for them to output
instead of
<
form class=”signup__sidebar”>
etc.
As the first variant is already coming out of the CMS just like that, but the second requires more coding work to get like that. And it is not just about the form, but any other plugins/extensions they use for the CMS.
How should this be seen?
In my example above variant one was:
and the second was:
I just call it .butts, as in buttons.
so it would be like,
.butts {}
.butts>span:first-of-type {}
.butts>span:last-of-type {}
I dunno why you would ever give children of these bad boys classes.
In my opinion, BEM is an absolute craziness and it makes HTML and CSS code bizarre.
Okay, even if your project is very complicated with a lot of stuff delivered by many teams, so why don’t follow Web Components approach that keeps everything clear and simple? http://webcomponents.org/
Because of it is not supported by browsers. And polyfills are very slow.
So, if I were to follow this structure, would this be appropriate for a navigation element?
And how much is too much? Say for example I have some small styled element in the link, like an icon, would that add a fourth layer? How far is too far when dealing with BEM? Can you go too far?
No.
Correct code would be:
@Sergey – You’ve got your elements and modifiers mixed up:
Try this:
Thanks David! I’m only good at canonical BEM naming:
This thread perfectly reveals how developers couldn’t catch BEM conventions right.
I use my own system as I’m not a fan of the BEM class names. I get the whole single selector thing but I find it much quicker creating templates with shorter class names.
Sub element class names always start with double underscore and modifiers with a single dash. I find it’s much easier to read in both the HTML and SCSS, for example:
HTML:
SCSS:
I do something similar but with the child combinator in internal selectors. Otherwise, you expose yourself to risk of regressions and selector battles when composing components. E.g. if this Accordion ends up composing an ArticleBlurb, which may have its own __content, then the Accordion’s __content styles will be applied to the ArticleBlurb’s. This is easily addressed with the child combinator:
You lose flexibility of adding arbitrary elements into the Accordion structure, but that’s a feature not a bug. A consistent structure makes components much easier to manage.
Knappster, I also do the same nesting style (along with Mike) but my naming convention is different.
Since “Accordion” and every other module class starts with an uppercase class name, I’m free to name a descendant class with any lowercase name since classes are case sensitive.
For more information on this naming convention: http://www.sitepoint.com/title-css-simple-approach-css-class-naming/
Keep in mind that we should also be focusing on the efficiency of our CSS. I would argue that efficiency should trump our ease of development when it comes down to it.
https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Writing_efficient_CSS
Nick, I strongly disagree. “Premature optimization is the root of all evil.” There is generally far greater risk to a project from unorganized CSS than from unoptimized selectors. Is performance/efficiency something to be aware of and understand? Yes. But it should not be the primary focus. Optimize only when necessary. Unlike most programming languages, CSS is a particularly sensitive software technology in this regard, as it doesn’t provide strong abstraction mechanisms behind which one can hide gnarly optimizations.
That said, there are other ways to optimize presentation than through selectors. Limit use of shadows and transparency. Prefer CSS3 transitions/animations to JavaScript ones. Concatenate stylesheets to reduce HTTP overhead.
Valid point, my example is a bit over simplified I think.
As a new web designer & developer it is useful for breakpoints for responsive design. Because codes are more cleaner.