BEM block, naming & nesting

There are a number of variants on how to write BEM classes, so be aware that are multiple competing standards. It started as a set of loose guidelines. Since posting this answer, Yandex has significantly overhauled their official standard (it's quite an improvement). The version of BEM I use is based heavily from an article by Nicolas Gallagher.

At this point I use "Atomic OOBEMITLESS", which is really just a way of saying that classes are modular and namespaced, selectors have low specificity, and states may be toggled with classes which allows CSS to be scaled, on top of a CSS preprocessor to make the code more concise and expressive.

All that said, I will be using the following BEM standard:

  • hyphenated class names as blocks:
    foo-bar
  • block name followed by __ followed by hyphenated class names for elements:
    foo-bar__fizz-buzz
  • block or element names followed by -- followed by hyphenated class names for modifiers:
    foo-bar--baz, foo-bar--baz__fizz-buzz, foo-bar__fizz-buzz--qux

BEM short form: block-name__element-name--modifier-name


You have three different blocks in your examples:

  1. sidebar, which has a sidebar__nav element
  2. content, which has a content__nav element
  3. nav, which has nav__item and nav__link elements

The sidebar and content blocks appear to be variations on the same block, and could be represented as .region.region--sidebar and .region.region--content.

The nav block is implicit on the ul element, and you should make it explicit:

<ul class="nav"><!-- could be content__nav or sidebar__nav as well if you choose -->
    <li class="nav__item"><a href="#" class="nav__link">LINK</a></li>
    <li class="nav__item"><a href="#" class="nav__link">LINK</a></li>
</ul>

Once you've specified that the ul element is a nav block, it makes sense to have the nav block be modified:

<ul class="nav nav--content">
    <li class="nav__item nav--content__item"><a href="#" class="nav__link nav--content__link">LINK</a></li>
    <li class="nav__item nav--content__item"><a href="#" class="nav__link nav--content__link">LINK</a></li>
</ul>

Once you've set up the CSS classes, styling all nav__item elements is simply:

.nav__item {
    ...styles here...
}

and overriding those styles for the content nav__item elements is:

.nav--content__item {
    ...styles here...
}

You should probably have a look at BEM's FAQ.

What would be a class name for an element inside another element? .block__elem1__elem2?

What should I do if my block has a complex structure and its elements are nested? CSS classes like block__elem1__elem2__elem3 look scaring. According to BEM method, block structure should be flatten; you do not need to reflect nested DOM structure of the block. So, the class names for this case would be:

.block{}
.block__elem1{}
.block__elem2{}
.block__elem3{}

Whereas the DOM representation of the block may be nested:

<div class='block'>
    <div class='block__elem1'>
        <div class='block__elem2'>
            <div class='block__elem3'></div>
        </div>
    </div>
</div>

Besides the fact that the classes look much nicer, it makes the elements be dependent on the block only. So, you can easily move them across the block when providing changes to the interface. The changes of the block DOM structure would not need corresponding changes to the CSS code.

<div class='block'>
    <div class='block__elem1'>
        <div class='block__elem2'></div>
    </div>
    <div class='block__elem3'></div>
</div>