← Back to CSS Course | Chapter 8: Animations & Effects | Lesson 21 of 22

CSS Architecture: BEM

As a stylesheet grows past a handful of pages, plain class names like '.card' or '.title' start colliding and getting confusing, whose card, whose title? BEM (Block, Element, Modifier) is a naming convention that solves exactly this problem, without requiring any new CSS features at all, just a consistent way of naming classes. In BEM, a Block is a standalone component (like a card), an Element is a part inside that block (like the card's title), and a Modifier is a variation of either (like a featured card). The naming pattern, block__element--modifier, makes every class name self-documenting just by reading it. Adopting BEM on a growing project like cookiescursor.com keeps class names predictable and searchable, even as the number of components and contributors grows.

What Is BEM?

BEM (Block, Element, Modifier) is a naming convention for CSS classes that makes a component's structure and variations obvious just from reading its class names, without needing to check the HTML or CSS to understand the relationship.

Note: BEM doesn't require any tooling or build step, it's simply a disciplined naming habit you can adopt on any project, including cookiescursor.com.

Warning: BEM is a naming convention, not a CSS feature, the browser doesn't enforce it, so consistency across a team relies on shared discipline.

Example: What Is BEM?

css
<style>
.cc-card {
  border: 1px solid #ccc;
}
</style>
<div class="cc-card">Obvious structure just from the class name</div>

Blocks

A Block is a standalone, reusable component, like a card, a navbar, or a button, named with a single clear class that represents the whole component.

Note: Name blocks after what they are, not where they're used, '.cc-card' can then be reused anywhere on cookiescursor.com, not just one page.

Warning: A block's class name should never depend on its parent container, that coupling is exactly what BEM is designed to avoid.

Example: Blocks

css
<style>
.cc-card {
  background: #f7f7f7;
  border: 1px solid #ddd;
  padding: 16px;
}
</style>
<div class="cc-card">A standalone, reusable component</div>

Elements

An Element is a part that only makes sense inside its block, named with a double underscore joining the block name and the element name, like block__element.

Note: If a piece of markup only ever appears inside one specific block, it's a strong candidate for an element class, not a standalone one.

Warning: BEM intentionally avoids chaining elements, like block__element__subelement, keep element names flat even for deeply nested markup.

Example: Elements

css
<style>
.cc-card {
  background: #f7f7f7;
  border: 1px solid #ddd;
  padding: 16px;
}
.cc-card__title {
  font-weight: bold;
}
</style>
<div class="cc-card">
  <h3 class="cc-card__title">Only makes sense inside cc-card</h3>
</div>

Modifiers

A Modifier represents a variation of a block or element, named with a double hyphen, like block--modifier or block__element--modifier, and is always used alongside the base class, never alone.

Note: Modifiers are perfect for states and variants, like a featured card, a large button, or a disabled input.

Warning: A modifier class should style only the difference from the base, not duplicate the base block's entire styling.

Example: Modifiers

css
<style>
.cc-card {
  background: #f7f7f7;
  border: 3px solid #ccc;
  padding: 16px;
}
.cc-card--featured {
  border-color: gold;
}
</style>
<div class="cc-card cc-card--featured">Base class plus a modifier</div>

BEM in Practice

In real projects, BEM's flat, explicit class names replace the need for deep CSS selector nesting, which keeps every rule's specificity low, consistent, and easy to override when needed.

Note: If you catch yourself writing a long nested selector like .card .header .title, that's usually a sign the markup would benefit from a BEM element class instead.

Warning: Mixing BEM class names with deeply nested selectors in the same project undermines the low, consistent specificity BEM is meant to provide.

Example: BEM in Practice

css
<style>
.cc-card {
  background: #f7f7f7;
  border: 1px solid #ddd;
  padding: 16px;
}
.cc-card__title {
  font-size: 18px;
}
</style>
<div class="cc-card">
  <div class="cc-card__title">Flat class instead of .card .header .title</div>
</div>
Common Mistakes
  1. Nesting elements inside elements in the class name, like block__element__subelement, when BEM intentionally keeps element names flat.
  2. Using a modifier class alone without the base block or element class also present on the same element.
  3. Reaching for deep CSS selector nesting instead of BEM's flat class names, which quietly reintroduces the specificity problems BEM avoids.
Chapter Summary
  • BEM stands for Block, Element, Modifier, a naming convention for writing clear, collision-free CSS class names.
  • A Block is a standalone component, an Element is a part of that block, and a Modifier is a variation of either.
  • The pattern block__element--modifier keeps class names flat, predictable, and self-documenting without deep nesting.
Browser Support

BEM is a naming convention, not a browser feature, so it works identically in every browser that supports CSS classes.

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.