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.
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:
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:
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:
<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:
<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:
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).
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:
<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.
What do you think?
How do you handle containers and wrappers when following the BEM methodology?
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 (1)
Thank you for this article, it was really helpful!!! I have one question and a problem.
Question: What is the vs code theme you 're using in this article, not the one posted here in dev.to but the one posted in your page scalablecss, with the orange and purple colors.
Problem: I tried to subscribe to get your free bem cheatsheet, but i'm not getting any email from you, checked junk and everythig.