BEM is a kind of superhero — it keeps the world of CSS safe from mess and clutter. I’d like to share what it is and why is it my way to go ever since I learnt it.
CSS is relatively easy to make it work. But keeping it working and clean in a long run is a whole different story — clutter sneaks in and, before you know it, you dream about starting it all from scratch. Sounds familiar? Perhaps it’s time for a naming convention. Different strokes for different folks — there are various options, of which my pick is BEM.
What BEM is
BEM is a class naming convention, allowing to write styles in a modular and maintainable fashion.
The abbreviation stands for Block‑Element‑Modifier, which are the only* three parts a class name can consist of. The notation goes like: ‘block__element — modifier’: name of class always starts with block name, then there’s element name (optional, prefixed with two underscores) and in the end the modifier (also optional, prefixed with two dashes).
Fig. 1: Example of component named in BEM
is a standalone, reusable group of items — you could think of it as of component in frontend frameworks. For example, a ‘card’ would make a good block.
Note: avoid content-specific names (like ‘shopping-list’) in favour of more generic ones (like ‘check-list’), so you can reuse them in different context (‘check-list’ would do fine for both shopping and todo list).
is a child element that only exists inside its block. Examples could be ‘card__title’, ‘card__text’ or ‘card__button’.
Note: there can be only one level of element nesting, so ‘card__button__text’ is a no-go. You should rather define another block called ‘button’ (consisting of ‘button__text’).
allows to provide additional variants for either block or element. This way we can have classes like ‘card — featured’ of ‘card__button — primary’.
Note: modifier class should only carry the modifications and always be accompanied with base class. For card it would be: ‘card card — featured’, where base class defines padding and border, while modifier class changes background color.
Fig. 2: Modifier in action
* Apart from three core BEM parts, you can also add namespace prefix.
Why is BEM G.R.E.A.T.
1. G for Global
BEM is one of the most recognized naming conventions out there. So if you are introducing a new team member to your BEM project, there’s a good chance they already know the convention, which reduces initial friction and allows them to be productive since day 1.
2. R for Readable
Thanks to descriptive class names given to basically every element, the stylesheet is easy to read on its own. Not only selectors look better, they also work faster than deeply nested ones.
Fig. 3: Readability of BEM vs tag selectors
3. E for Expandable
As the specificity of CSS selectors is minimal, adding another variation is very simple. Single modifier class should be enough — no more ‘at least equal selector weight’ toil.
Fig. 4: Overriding styling of secondary menu icon (BEM vs. nested tags)
4. A for Adaptable
Sharing the philosophy of modularity, BEM naturally works fine with frameworks. Also, styling is independent of elements type and nesting, making it less prone to break when tackling with document structure.
Fig. 5: Importance of element type and nesting (BEM vs. tags)
5. T for Tough
There are only two hard things in Computer Science: cache invalidation and naming things.
— Phil Karlton
When you start following BEM (fully and honestly), you’ll probably find yourself struggling with it constantly. Paradoxically, it’s a good thing:
- finding proper block names makes the code clean and legible to others (your future self included)
- grappling with synonyms encourages reusing existing blocks
- avoiding multi-level nesting makes you rethink document structure
In short, it will make you push yourself to pay attention to detail, think things through and thus raise the quality of your code. Ready to start?