Objective

I've been trying to wrap my head around how to apply BEM and the pros and cons of using it (or something like it). For those of you that are unfamiliar, BEM (stands for Block Element Modifier) is mostly about how to write classes in HTML. You end up with much longer classes than you're probably used to, but you will understand what's being built just by reading the selectors; before you even look at the markup.

Another tenet of a lot of these CSS frameworks is keeping low specificity by using class selectors, and not tag selectors. The issue with tag selectors is how the CSS is read by the browser. Choosing to use classes and not ID's is to keep specificity low.

Here's the rendered result in Codepen

Below is a breakdown of how I wrote my classes and markup:

div.page
header.page__header
div.page__header__logo.logo
a.logo__link
nav.page__header__siteNav.siteNav.siteNav--primary
ul.siteNav__list
li.siteNav__listItem.siteNav__listItem--products
a.siteNav__link
li.siteNav__listItem.siteNav__listItem--customerService
a.siteNav__link
li.siteNav__listItem.siteNav__listItem--aboutUs
a.siteNav__link
li.siteNav__listItem.siteNav__listItem--contactUs
a.siteNav__link
section.page__region.page__region--primary
article.page__content.content.content--main
img.content__media.media--primary.media--image
div.content__textWrapper
h1.content__headline.headline--primary
p
ul
li
li
li
p
p
p
aside.page__region.page__region--secondary
article.region--secondary__content.content
a.content__teaserLink.content__teaserLink--wrapper
img.content__media.media--primary.media--image
h3.content__headline.headline--primary
p.content__teaserCopy
article.region--secondary__content.content
a.content__teaserLink.content__teaserLink--wrapper
img.content__media.media--primary.media--image
h3.content__headline.headline--primary
p.content__teaserCopy
article.region--secondary__content.content
a.content__teaserLink.content__teaserLink--wrapper
img.content__media.media--primary.media--image
h3.content__headline.headline--primary
p.content__teaserCopy
article.region--secondary__content.content
a.content__teaserLink.content__teaserLink--wrapper
img.content__media.media--primary.media--image
h3.content__headline.headline--primary
p.content__teaserCopy
footer.page__region.page__region--footer
nav.siteNav.siteNav--tertiary
ul.siteNav__list
li.siteNav__listItem
a.siteNav__link
li.siteNav__listItem
a.siteNav__link
li.siteNav__listItem
a.siteNav__link
li.siteNav__listItem
a.siteNav__link

A bit of background

My Bias

I think it's important to note that I'm used to building larger scale sites, and I'm used to being an in-house CSS developer. My concerns are with maintainability and scalability in a CMS environment.

At this point, I only write my CSS in a preprocessor (preferably SASS).

Other frameworks I've looked at or tried

I used Twitter's Bootstrap for a time, it was good for it's features, and I didn't have to write it myself; but it has too much bulk.

I'm not a fan of OOCSS because:

  • I didn't like the naming conventions of classes
  • I don't like amount of classes that resulted, the framework assumes you need a large site
  • I loathe the idea of always having to change markup (classes) when I want to change the presentation (I don't expect to never have to change classes, but it seems a guaruntee that they change if the presentation is altered)
  • Some of the naming conventions describe presentation pretty closely. This can be very troublesome when dealing with responsive layouts and presentation changes.

OOCSS and Atomic Stylesheets seem like a really good idea if an application compiles your markup and your styles from higher level code. In my world I write templates, and then I write styles. I'm not a huge fan of back and forth.

Balancing Developer Time to Web Performance

Let's start with: I care about CSS performance; but I'm making muscle cars, not Ferraris.

I'm used to making larger scale sites, but not your Google or Facebook type 'large'. We don't have teams of people dedicated to performance, and CSS typically has a lower impact on page load/render time.

If I were in that position, OOCSS and Atomic CSS would make more sense for my use.

The difference between rendering page that has 4,000 CSS rules vs. 18,000 rules is ~300ms in IE7. My entire site's CSS is usually ~4000 lines (not rules, lines).

If I can make myself or my team more effective and aid collaboration, I usually find more gains there than the effort I'd spend making the site a few ms more performant.

Some assumptions I made in my code:

I assumed that the content area of an article would be out of my control. Text markup (p, ul, li, etc) would be there, added by a content user via a WYSIWYG editor. You may notice a series of p, ul and li tags with no classes. Everything else I assumed would be markup I could control pretty tightly.

Resulting thoughts on BEM

Let's start with the cons:

  • It slows me down when writing markup. Mostly because I'm thinking more about my naming and the -/_ are harder to hit than a-z.
  • The verbose class names make the HTML a little harder to read... that is if you really have to read it, which I generally don't spend much time doing.
  • It goofs with my Editor of choice(Sublime Text), mostly when I'm writing the HTML. Tab completion and navigating the code with the keyboard isn't as easy.
  • Most BEM implementations I've seen use dashes to seperate words, e.g.
    multi-word-class__sub-element--modifier-name
    That's kind of an exaggeration, but when you're looking at a sea of class names, it's important. What I'm liking better is camel case, so:
    multiWordClass__subElement--modifierName

To be frank, I don't think those cons are great reasons to judge a front-end framework. These are both acceptable beefs if I get some good benefits.

Which brings us to the pros:

  • My CSS has an very low specificity. As the codebase grows the specificity's growth will likely be slower (hopefully specificity can stay just as low). The most authoratative selectors I have consists of 2 classes!

    Maintainability ++
    Scalability ++

  • BEM naming conventions are much more legible and explicit in their meaning. It also enforces a naming convention that I find easy to follow, and I think other people would write similar classes to mine, making this easier to hand off.

    Maintainability ++
    Scalability++

  • Very preprocessor friendly (at least for SASS 3.3+ and Stylus)

    Maintainability ++

  • My SASS code is easier to read. I don't know if everyone would agree with this, but I'm nesting more with less specificity thanks to SASS 3.3's ability to concatenate selector names with the &. This is super helpful when I have to pick through my code to find where I stuck a style.

    Maintainability ++
    Scalability ++

  • This will map very neatly to a CMS' structure, which for me is a big deal. Fighting to get your classes where you want them in the 'view' or 'theme' layer is not a good way to spend your time.

    Scalability ++

Conclusion

I'm a fan. I'm a big fan. This is a great way to write CSS for large scale sites that have to be kept up over long amounts of time.

My Inspiration for this little experiment:


8,362 9 21