Search code examples
htmlcssbem

Correct approach for a navbar structure with BEM


I'm trying to wrap my head around BEM naming in CSS and am wondering if I'm understanding it correctly.

Per the official docs, an element is:

A part of a block that has no standalone meaning and is semantically tied to its block.

Given the code snippet below, none of the child items of .main-nav has any standalone meaning, so I believe they all qualify as an element.

However, I can't help but feel like there is some code smell when I end up with a class name like .main-nav__sub-menu-item-link. It feels like I'm still nesting several layers deep, just within my element name space.

Maybe this is perfectly OK and example below is the correct implementation, I'd just appreciate a second opinion.

<nav class="main-nav">
  <div class="main-nav__logo">
    <a class="main-nav__logo-link">Company Name</a>
  </div>
  <ul class="main-nav__menu">
    <li class="main-nav__menu-item">
      <a class="main-nav__menu-item-link">Products</a>
      <ul class="main-nav__sub-menu">
        <li class="main-nav__sub-menu-item">
          <a class="main-nav__sub-menu-item-link">Foo</a>
        </li>
        <li class="main-nav__sub-menu-item">
          <a class="main-nav__sub-menu-item-link">Bar</a>
        </li>
        <li class="main-nav__sub-menu-item">
          <a class="main-nav__sub-menu-item-link">Baz</a>
        </li>
      </ul>
    </li>
    <li class="main-nav__menu-item">
      <a class="main-nav__menu-item-link">Services</a>
    </li>
    <li class="main-nav__menu-item">
      <a class="main-nav__menu-item-link">About Us</a>
    </li>
  </ul>
</nav>


Solution

  • It's really ok indeed.

    The issue with absence of scoping in CSS is solved in your markup. Selectors specificity won't increase. So just keep it as is.

    And don't be afraid of long classnames, after gzip it's just the same as with short variant.