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’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.
Here’s a screenshot from Airbnb’s home page:
Thinking with your BEM hat on, you’ll notice:
.card
)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…
Take a look at this design from the Notion.so home page:
Again, thinking with your BEM hat on, you’ll notice:
.feature
)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>
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.
Levelling up your CSS & Sass skills in 2021 is a great idea. Here's why: