</> ConvertAtlas Developer Tools
Level 3 · Advanced — Modern CSS Lesson 33 Advanced 13 min

BEM and Naming Systems

Block-Element-Modifier and other conventions for predictable, conflict-free class names.

Naming is one of the hardest parts of CSS at scale. A good convention makes class names predictable, self-documenting and conflict-free, so any developer can read the HTML and understand the structure. BEM is the most widely used.

What BEM is

BEM stands for Block, Element, Modifier. A block is a standalone component (<code>card</code>). An element is a part of it, joined with two underscores (<code>card__title</code>). A modifier is a variant, joined with two hyphens (<code>card--featured</code>).

.card__title--large
  • Blockcard
  • Element (__)title
  • Modifier (--)large
HTML
<div class="card card--featured"><h3 class="card__title">Title</h3><p class="card__text">Body</p></div>
CSS
.card{background:#fff;border:1px solid #e2e8f0;border-radius:10px;padding:16px}
.card--featured{border-color:#2563eb;box-shadow:0 6px 18px rgba(37,99,235,.15)}
.card__title{margin:0 0 6px}
.card__text{margin:0;color:#64748b}
Result
Block (card), element (card__title), modifier (card--featured).

Why BEM works

Every class is a single, flat class selector — so specificity stays low and equal. Names are unique and self-describing, so there are no accidental conflicts and the HTML reads like documentation. You never need to nest selectors to scope styles.

Nested selectors vs BEM
Nested (fragile)
  • .card .title { }
  • High, uneven specificity
  • Breaks if structure changes
  • Hard to override
BEM (robust)
  • .card__title { }
  • Flat, equal specificity
  • Independent of nesting
  • Easy to override

BEM and utility classes together

Modern projects often combine BEM components with utility classes (single-purpose helpers like <code>.mt-4</code> or <code>.text-center</code>). BEM describes components; utilities handle one-off spacing and tweaks. Both stay low-specificity.

Common mistake
Don't
.cardTitle, .card-title, .CardTitle
Do
.card__title /* one consistent convention */

Inventing inconsistent names (.cardTitle, .card-title, .card_title) across a codebase, causing confusion and duplicate styles. Pick one convention and stick to it.

Best practice

Adopt one naming convention (BEM is a safe default) project-wide. Keep blocks reusable, name by purpose not appearance (.btn--primary, not .btn--blue), and combine with utility classes for one-offs.

Try it yourself

Take a card component and rewrite its classes in BEM: a card block, card__title and card__text elements, and a card--featured modifier. Notice every selector is a single flat class.

Quick quiz

1. In BEM, what joins an element to its block?

2. What does a modifier (--) represent?

3. Why does BEM keep specificity low?

4. Best naming practice?

Key takeaways
  • BEM = Block, Element (__), Modifier (--) for predictable names.
  • Every BEM class is a flat selector, keeping specificity low and equal.
  • Names are self-documenting and conflict-free — no nesting needed.
  • Name by purpose, not appearance, and combine with utility classes.