naming BEM sub blocks

jeremyhoover picture jeremyhoover · Mar 28, 2014 · Viewed 11.7k times · Source

I'm using a BEM approach to writing html + css. With this syntax:

  • Blocks: block_name
    • Elements: block_name__element_name
    • Modifiers: block_name__element_name--modifier

I get confused when I have a block within another block. For instance, in a header, I want the header to be a block that I can reference and the nav and logo to be blocks. I want to reference those nav and logo blocks as being the within the site_header. But, how would I write that? Chaining blocks like block_name__sub_block_name seems quite long.

Does anyone have a typical way they would write this example?

<div class="site_header__logo">
    <a class="site_header__logo__link">
        <img class="site_header__logo__image">
    </a>
</div>

<nav class="site_header__main_nav">
    <ul>
        <li class="site_header__main_nav__item">
            <a class="site_header__main_nav__link">Home</a>
        </li>
        <li class="site_header__main_nav__item">
            <a class="site_header__main_nav__link">About Us</a>
        </li>
        <li class="site_header__main_nav__item">
            <a class="site_header__main_nav__link">Contact Us</a>
        </li>
    </ul>
</nav>

<div class="site_header__phone">
    <p class="site_header__phone__number">
        555.555.5555
    </p>
</div>

Answer

katranci picture katranci · Mar 30, 2014

I think the logo, main header, and phone fit in the definition of block which is given in BEM website as:

A block is an independent entity, a "building block" of an application. A block can be either simple or compound (containing other blocks).

What you have got is three simple blocks (logo, main_nav, and phone) within a compound block (site_header). It is actually very similar to the HEAD compound block that is given as an example on the BEM methodology definitions page.

So I would write it this way:

<div class="logo">
    <a class="logo__link">
        <img class="logo__image">
    </a>
</div>

<nav class="main_nav">
    <ul>
        <li class="main_nav__item">
            <a class="main_nav__link">Home</a>
        </li>
        <li class="main_nav__item">
            <a class="main_nav__link">About Us</a>
        </li>
        <li class="main_nav__item">
            <a class="main_nav__link">Contact Us</a>
        </li>
    </ul>
</nav>

<div class="phone">
    <p class="phone__number">
        555.555.5555
    </p>
</div>

If you think that "logo" is way too generic as a name and wouldn't represent the other types of logos in the project feel free to give it a different name like "company_logo".

In terms of styling, BEM suggests using block modifiers and element modifiers to represent their different styles. For example if you wanted to have your phone number in bold, then you can create a class modifier for it in CSS and apply it to your HTML as follows:

.phone__number--bold {
    font-weight: bold;
}

<div class="phone">
    <p class="phone__number phone__number--bold">
        555.555.5555
    </p>
</div>

Modifiers are the preferred way over styling blocks within other blocks. So don't do this:

.site_header .phone__number {
    font-weight: bold;
}

I think there is one exception to this which is when you want to give "location-dependant styles" to the block inside. Let's say that you want to give a left margin to the "logo" block. Instead of creating a modifier like:

.logo--push_20 {
    margin-left: 20px;
}

it is better to follow OOCSS second principle - Separate container and content - and leave the job to the container:

.site_header .logo {
    margin-left: 20px;
}