BEM Class Naming
Problem
CSS class names lack consistent structure, making it unclear which elements belong together or how they relate. Developers create names like btn-primary
, button-large
, and big-blue-button
for the same component, leading to confusion about which classes to use and difficulty understanding the codebase hierarchy.
Solution
Use the Block__Element--Modifier
naming convention where blocks are standalone components, elements are parts of blocks, and modifiers represent variants or states. This creates self-documenting class names that clearly express relationships and make the component structure visible in the markup.
Example
This example shows a card component marked up using BEM naming convention, where the block is “card”, elements are prefixed with “card__”, and modifiers use ”—”.
<!-- Block: card, with a modifier indicating it's featured -->
<div class="card card--featured">
<!-- Element: title, part of the card block -->
<h2 class="card__title">Title</h2>
<!-- Element: text, part of the card block -->
<p class="card__text">Content</p>
<!-- Element: button, with a modifier for the primary variant -->
<button class="card__button card__button--primary">
Click me
</button>
</div>
Benefits
- Creates self-documenting class names that express component relationships.
- Reduces naming conflicts through consistent prefixing conventions.
- Makes component structure immediately visible in the markup.
- Makes it easier to understand which elements belong to which blocks.
- Works well with CSS preprocessors and doesn’t require JavaScript.
Tradeoffs
- Results in very long class names that increase HTML size.
- Requires team discipline to maintain naming conventions consistently.
- Can feel verbose and repetitive compared to utility-first approaches.
- Harder to apply to deeply nested component structures.
- May conflict with component-scoped CSS solutions in modern frameworks.