- Webknit
- WON
- Base
I gave a talk at work and figured it would be good to stick the notes on here in case they help others. There are much better posts out there on BEM, including Harry’s excellent write up, I got to grips with BEM via his article and also based some of this post on his words.
HTML semantics and FE architecture are both difficult tasks that requires a naming convention in order to ensure that projects scale well and are maintainable.
Three key important aspects of developing include:
A naming convention can assist with all of the above. At first I was sceptical as to why I needed to do this. But now 3/4 months down the line I would say it’s one of the best – and easiest – methods that I’ve adopted since university. For small projects it’s probably not going to make much difference, but for sites with multiple pages it will. I think it’s important to adopt a naming convention as standard regardless of project size.
Here’s how the classes look.
// block .header // element .header__navigation //modifier .header--right
Let’s have a look at a HTML example without a naming convention
<div class=“left-box”> <div class=“links”> <ul> <li><a>link</a></li> </ul> </div> </div>
Couple of problems with this.
I want to change the colour of those links using SASS. Here’s how most people do it.
.left-box { .links { ul { li { a { color: red; } } } } } //That outputs the following .left-box .links ul li a {color: red;}
That means nesting five deep to change the colour of that <a> tag. You should never really nest lower than 3 levels of CSS, if you are then you should consider modifying your css or refactoring your markup.
A quick comment on the above bit of code before I move back onto BEM. The ul and li elements don’t need to be nested. The further you nest the harder the browser has to work, take them out. I go into more detail about this below, and also in this post.
Lets rework the previous code example using BEM.
<div class=“content-box”> <div class=“content-box__links”> <ul class=“content-box__links-ul”> <li><a>link</a></li> </ul> </div> </div>
Here’s a perfect CSS example of how we shoudl target that <a> tag. Bear in mind that SASS should out also output your CSS preference.
.content-box__links-ul a {color: red;}
BEM really helps performance when writing SASS/LESS. We can write the following.
.content-box { &__links { } &__links-ul { a { colour: red; } } }
This may look like we’re nesting, but SASS actually outputs exactly the same as the vanilla CSS mentioned above. The &__ bit takes the parent class name and combines it to the element.
Also notice above how I separated the &__links and the &__links-ul, there’s no reason to have them nested.
I can make the above code even faster, neater more modular, BUT I think it’s overkill. Going deeper into BEM could cause more problems that it’s worth. I generally use the previous method but I have thought a lot about the following.
<div class=“content-box”> <div class=“content-box__links”> <ul class=“content-box__links-ul”> <li class=“content-box__links-li”> <a class=“content-box__links-a”>link</a> </li> </ul> </div> </div> // SASS .content-box { &__links { } &__links-ul { } &__links-li { } &__links-a { color: red; } } // Outputs .content-box__links-a { colour: red;}
Now you can see that there’s no nesting whatsoever. Everything has been split and it’s extremely modular. However this means that your HTML is more bloated. At this level, BEM can be very subjective and you need to decide which method is best for you. I’m interested to hear how deep everyone else goes, so if you’ve any comments to make on this hit me up on twitter
So I’ve mentioned the block and elements, but what about the modifier? Consider the following:
<div class=“content-box content-box--right”> <div class=“content-box__links”> <ul class=“content-box__links-ul”> <li><a>link</a></li> </ul> </div> </div> .content-box { float: left &--right { float: right; } }
We can simply add an extra class to the content-box which represents a different state of our block and define that in our SASS, there’s no need to duplicate styles and add left or right. Which brings me nicely onto the next topic.
Another important aspect of a naming convention is that it gives us the opportunity to separate structure from skin(visual appearance). Have a read of this Smashing mag post for more info.
Imagine our content-box__links appears on three pages, and they’re going to have three different background colours, white(default), blue and green. We’re also going to need the links to be different colours red(default), white and blue. Using the content-box–right technique we discussed previously, we can separate our styling and structure.
<div class=“content-box”> <div class=“content-box__links content-box__links--blue”> <ul class=“content-box__links-ul”> <li><a>link</a></li> </ul> </div> </div> .content-box { float: left &__links { display: block; width: 50%; &--white { background: white; a { color: red; } } &--blue { background: blue; a { color: white; } } &--green { background: green; a { color: blue; } } } }
Using this code we can make use of the content-box__links–blue class to add presentation to our element while the structure rules are kept separate. By doing this we have complete control of our code, we can reuse elements very easily and add additional classes for presentational purposes.
I hope this has been of some help, and as always feel free to hit me up on twitter .
Thanks for reading.
Shane