Question

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>

Was it helpful?

Solution

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;
}

OTHER TIPS

You could also have a look on 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>

Yep, you can strip out a lot within the class names. For example:

HTML:

`

<nav class="site_header">
    <ul>
        <li class="nav_item">
            <a class="nav_link">Home</a>
        </li>
        <li class="nav_item">
            <a class="nav_link">About Us</a>
        </li>
        <li class="nav_item">
            <a class="nav_link">Contact Us</a>
        </li>
    </ul>
</nav>

`

Then within your CSS put:

`

.site_header { 
    ... stuff ...
}

.site_header .nav_item {
    ... nav_item stuff ...
}

.site_header .nav_link {
    ... nav_link stuff ...
}

`

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top