Please Support - Ride for the child

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.

What is it?

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:

  • keeping code maintainable
  • keeping code transparent and readable both for us and the browser
  • keep code scalable, especially CSS.

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.

What does BEM mean?

  • block – represents the parent
  • element – represents a child of the block
  • modifier – represents a different state or version of block or element

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.

  • The semantics are pretty poor the class names have no meaning
  • Looking at it I can’t really tell much without running the code
  • I presume left box is on the left? What if it moves to the right?
  • Are any styles for the left box used anywhere else? If so then they’re probably being duplicated.

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.

It can get complicated

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 @webknit

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.

OOCSS

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 @webknit.

Thanks for reading.

Shane