Sal's Blog

A Less Fugly BEM

Introduction

user

Sal Lara

Sal is a senior web developer specializing in dev/design workflows, frontend and devops. He also enjoys robotics, making music, and puppies. He doesn't have any free time, but he does have a wife and two babies who make him very happy.


Featured

CSS

A Less Fugly BEM

Posted by Sal Lara on .

BEM has brought me some much-needed sanity to several CSS codebases getting too big for their britches. But it’s freakin’ hideous. I recently came up with a simple tweak to the BEM syntax which, although fairly blasphemous, adds semantic meaning and—in the eyes of the author, at least—is a fair bit less fugly to behold.

Big CSS codebases can get away from you because there’s very little structure imposed by the language. Luckily things like BEM have come along to help rein in the wildness. It’s simple, and it truly works. But oh man, is it hideous.

And there are couple of other flaws to it. I recently imagined a solution which addresses at least a couple of those, including the fugliness. Full disclosure: It involves camel-case. If your stomach can handle it, read on and hear me out. Otherwise, you’re now excused.

Example

Take the ‘Hello World’ of component CSS examples, a button:

<a class="btn btn--big btn--orange" href="http://css-tricks.com">
  <span class="btn__price">$9.99</span>
  <span class="btn__text">Subscribe</span>
</a>

The reason that BEM doubles up the underscores and dashes is to differentiate itself from class names that may be using them. By using camelcase, it becomes sufficient to just use a single underscore and/or dash:

<a class="Btn Btn-big Btn-orange" href="http://css-tricks.com">
  <span class="Btn_price">$9.99</span>
  <span class="Btn_text">Subscribe</span>
</a>

The above isn’t a great example, though—it’s not until you get into some heavier blocks that you experience the true fugliness of BEM syntax (I love you, Yandex! I appreciate and cherish you, Yandex!):

<nav class="global-nav global-nav--compact">
  <ul class="global-nav__list global-nav__list--compact">
    <li class="global-nav__list-item global-nav__list-item--compact">
      <a href="#"><pp-brand color="#f8f8f8"></pp-brand></a>
    </li>

    <li style="flex:1;"></li>

    <li class="global-nav__list-item global-nav__list-item--compact">
      <a class="global-nav__nav-link" href="/search">Search</a>
    </li>

    <li class="global-nav__list-item global-nav__list-item--compact">
      <a class="global-nav__nav-link" href="/help">Help</a>
    </li>

    <li class="global-nav__list-item global-nav__list-item--compact">
      <a class="global-nav__nav-link" href="/about">About</a>
    </li>

    <li class="global-nav__dropdown">
      <a class="global-nav__dropdown-link" href="#">Richard Hendricks</a>
      <img class="global-nav__dropdown-avatar" src="/img/avatar.png"/>
    </li>
  </ul>
</nav>

Now using camel-case:

<nav class="GlobalNav GlobalNav-compact">
  <ul class="GlobalNav_list GlobalNav_list-compact">
    <li class="GlobalNav_listItem GlobalNav_listItem-compact">
      <a href="#"><pp-brand color="#f8f8f8"></pp-brand></a>
    </li>

    <li style="flex:1;"></li>

    <li class="GlobalNav_listItem GlobalNav_listItem-compact">
      <a class="GlobalNav_navLink" href="/search">Search</a>
    </li>

    <li class="GlobalNav_listItem GlobalNav_listItem-compact">
      <a class="GlobalNav_navLink" href="/help">Help</a>
    </li>

    <li class="GlobalNav_listItem GlobalNav_listItem-compact">
      <a class="GlobalNav_navLink" href="/about">About</a>
    </li>

    <li class="GlobalNav_dropdown">
      <a class="GlobalNav_dropdownLink" href="#">Richard Hendricks</a>
      <img class="GlobalNav_dropdownAvatar" src="/img/avatar.png"/>
    </li>
  </ul>
</nav>
user

Sal Lara

http://natchiketa.com

Sal is a senior web developer specializing in dev/design workflows, frontend and devops. He also enjoys robotics, making music, and puppies. He doesn't have any free time, but he does have a wife and two babies who make him very happy.