How To Name Containers And Wrappers In BEM

February 18, 2020

Are you unclear on BEM best practices for the naming conventions of wrapper and container CSS classes?

For example, you might have multiple blocks and you need to add a wrapper class to style the positioning of those blocks.

What is BEM best practice for naming wrapper classes? What’s the best way to position the 3 blocks using the BEM Methodology?

It becomes difficult to know how to name wrapper and container classes as they fall out of the ‘block, element & modifier’ mental model.

Let’s dive right in and look at ways to solve this.

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

Repeated Wrappers: Airbnb Example

Here’s a screenshot from Airbnb’s home page:

Airbnb Experiences

Thinking with your BEM hat on, you’ll notice:

  • Each card can be considered a BEM block (e.g. .card)
  • A wrapper is required to position the 5 blocks horizontally

Here’s how the HTML would be structured following the BEM convention:

<div class="..."> <!-- Wrapper class goes here -->
<div class="card">
<img class="card__img" src="..." alt="...">
<h4 class="card__subtitle">...</h4>
<p class="card__description">...</p>
<div class="card__rating">...</div>
</div>
<div class="card">...</div>
<div class="card">...</div>
<div class="card">...</div>
<div class="card">...</div>
</div>
<style>
.card {}
.card__img {}
.card__subtitle {}
.card__description {}
.card__rating {}
</style>

In fact, other sections of the Airbnb home page follow a similar structure. For example, the ‘Airbnb Plus’ section uses 3 columns instead of 5: Airbnb Plus

So the question is:

What is the BEM best practice naming convention for the wrappers?

In this case, as there are repeated patterns of how the wrappers work, the best approach would be to use a generic wrapper name like .grid.

This allows you to use the wrapper in multiple places as it’s not constrained with semantic meaning.

For example, here’s how the HTML could look for the Airbnb Experiences section:

Airbnb Experiences

<div class="grid grid--experiences">
<div class="card">...</div>
<div class="card">...</div>
<div class="card">...</div>
<div class="card">...</div>
<div class="card">...</div>
</div>
<style>
.grid {
display: grid;
grid-column-gap: 1rem;
}
.grid--experiences {
grid-template-columns: repeat(5, 1fr);
}
.card {}
</style>

And here’s the Airbnb Plus section:

Airbnb Plus

<div class="grid grid--plus">
<div class="card">...</div>
<div class="card">...</div>
<div class="card">...</div>
</div>
<style>
.grid {
display: grid;
grid-column-gap: 1rem;
}
.grid--plus {
grid-template-columns: repeat(3, 1fr);
}
.card {}
</style>

Using modifiers to tweak the layout, like .grid--experiences and .grid--plus allows you to use a generic wrapper that can be applied at scale across the design.

Pretty cool, eh?

But you might be thinking…

How about in the example where the wrapper isn’t a repeated pattern?

Like a 1-off design that requires a wrapper to style a collection of BEM blocks?

This will require a slightly different approach…

Unique Wrappers: Notion Example

Take a look at this design from the Notion.so home page:

Notion.so features

Again, thinking with your BEM hat on, you’ll notice:

  • Each quarter can be considered a BEM block (e.g. .feature)
  • A wrapper is required to position the 4 blocks

Here’s how the HTML could be structured following the BEM convention:

<div class="..."> <!-- Wrapper class goes here -->
<div class="feature">
<img class="feature__img" src="..." alt="...">
<h3 class="feature__title">...</h3>
<p class="feature__description">...</p>
</div>
<div class="feature">...</div>
<div class="feature">...</div>
<div class="feature">...</div>
</div>
<style>
.feature {}
.feature__img {}
.feature__title {}
.feature__description {}
</style>

There’s an important difference between this example and the previous Airbnb example:

Looking at the design of the entire Airbnb page, it’s clear that the layout of each section uses a consistent format, with slight variations (like the number of columns).

Airbnb home page layout

The Notion feature section, however, is contextually unique. I.e. there are no other similar sections across the website.

Therefore, instead of using a generic naming convention for the wrapper as we did for Airbnb, a different naming convention approach is required for the wrapper in the Notion example.

The naming convention best approach would be to use a wrapper specific to the blocks, like features-wrapper.

For example, here’s how the HTML could look for the Notion features section:

Notion.so features

<div class="features-wrapper">
<div class="feature">...</div>
<div class="feature">...</div>
<div class="feature">...</div>
<div class="feature">...</div>
</div>
<style>
.features-wrapper {
display: grid;
grid-column-gap: 1rem;
}
.feature {}
</style>

Conclusion

So the key to naming wrapper and container classes within the BEM mental model is considering the context:

Is this layout a repeated pattern that can be leveraged in many areas?

If so, use a generic class name like .grid or .container.

Or is this layout unique to a collection of blocks?

In this case, use a class name related to the blocks you’re positioning. So if you need a wrapper class for a bunch of .card blocks, then cards-wrapper would work well.

Want to become an advanced CSS & Sass developer?

Levelling up your CSS & Sass skills in 2021 is a great idea. Here's why:

  • Increase your employability and value as a front-end developer
  • Learn how to style your websites and applications in clean, efficient code
  • Use tooling and techniques like BEM, flexbox, grid & more to improve your code
Scalable CSS LogoView recommended course on Udemy
Tom Ray

By Tom Ray, a front-end developer who lives in London with his fiancée and cat Arnold.

© Scalable CSS 2021, built with ❤️ in London, UK.