DEV Community

Tom Ray
Tom Ray

Posted on • Originally published at scalablecss.com

BEM Grandchildren: How To Handle Deeply Nested Elements

Understanding the basic concept of BEM (block, element, and modifier) is a fairly simple concept to grasp.

However, things can start to easily go out of control when elements start to get 3 or 4 layers nested deep within a block.


Bonus: Download a free cheat sheet that will show you how to quickly get started with BEM.


These nested elements are typically known as 'grandchild' elements (as they're nested 2 levels deep).

bem-granchild-image.png

In this article, I'll tackle how to solve these common issues and follow BEM best practices.

Ready? Let's dive in.

Chaining Elements Together - The Typical Grandchild Mistake

Here’s how many people solve for nesting elements within elements with BEM:

<div class=“nav”>
    <ul class=“nav__menu”>
        <li class=“nav__menu__item”>
            <a class=“nav__menu__item__link”>Home</a>
        </li> 
    </ul>
</div>
Enter fullscreen mode Exit fullscreen mode

Following this method of chaining elements (like this: .nav__menu__item__link) gets out of control pretty quickly.

It makes your class names difficult to read, not to mention it'll unnecessarily bloat your HTML and CSS files.

This approach also follows the structure of the DOM, which limits your flexibility if the structure of your HTML changes.

Don't just take my word for it. Vladimir Grinenko is on the Yandex team (the creators of the BEM methodology) and said this:

"BEM methodology doesn't recommend to use elements within elements in class names. You don't need to resemble DOM structure in naming. Having one level structure makes refactoring much easier."
— Vladimir Grinenko, Yandex

For example, imagine that you realised that you needed to add a <div> inside the <nav>:

<div class=“nav”>
    <div class="nav__wrapper"> <!-- Here is my new div-->
        <!-- Now I need to refactor all the classes below
        because of the new div -->
        <ul class=“nav__wrapper__menu”>
            <li class=“nav__wrapper__menu__item”>
                <a class=“nav__wrapper____menu__item__link”>Home</a>
            </li> 
        </ul>
    <div>
</div>
Enter fullscreen mode Exit fullscreen mode

All the classes within the <div> would need to be updated, as well as updating the class names in your CSS file.

So as you can see, taking the Block__Element__Element__Element is not a long term, sustainable choice.

Here's how to better solve it:

The Grandchild Solution

Instead of chaining elements like nav__menu__item__link, simply focus on the block name itself and use that as the main anchor:

<div class=“nav”>
    <ul class=“nav__menu”>
        <li class=“nav__item”>
            <a class=“nav__link”>Home</a>
        </li> 
    </ul>
</div>
Enter fullscreen mode Exit fullscreen mode

Taking this approach also makes your code much more readable for other developers, as they can easily see all the elements that have a relationship with the block (in this case: .nav).

And if you need to add or remove HTML elements in the future, no refactoring is required:

<div class=“nav”>
    <!-- New div added without the need to refactor -->
    <div class="nav__wrapper"> 
        <ul class=“nav__menu”>
            <li class=“nav__item”>
                <a class=“nav__link”>Home</a>
            </li> 
        </ul>
    </div>
</div>
Enter fullscreen mode Exit fullscreen mode

If you find yourself entering territory where your elements are more than 3 levels deep, you might need to reconsider the structure of the block, potentially even breaking the block into smaller chunks.

And that's it!

I hope this article has helped you solve the 'Grandchild' scenario moving forward.


Download Free BEM Cheat Sheet

Want to start practicing BEM and looking for a no-nonsense, quick start action guide?

Download a free cheat sheet covering BEM basics so you can dive in and start practicing today.

Top comments (2)

Collapse
 
sebbdk profile image
Sebastian Vargr

Nesting is the devils anus in my opinion/experience.
And grandchildren is just another way to do it. :)

So I totally agree, if you have to BEM, at least scale it as horizontally as possible. :)

Collapse
 
bytomray profile image
Tom Ray

Nesting can indeed be super annoying.

Glad you agree and enjoyed the article!