CSS Architecture: BEM
In this page:
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?
<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
<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
<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
<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
<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>
- Nesting elements inside elements in the class name, like block__element__subelement, when BEM intentionally keeps element names flat.
- Using a modifier class alone without the base block or element class also present on the same element.
- Reaching for deep CSS selector nesting instead of BEM's flat class names, which quietly reintroduces the specificity problems BEM avoids.
- 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.
BEM is a naming convention, not a browser feature, so it works identically in every browser that supports CSS classes.
Chapter Quiz — Complete all 22 topics to unlock
0/22 topics done
Complete these topics first:
- CSS Gradients
- CSS Shadows
- CSS Filters
- CSS Blend Modes
- CSS Transforms
- CSS 2D Transforms
- CSS 3D Transforms
- CSS Transitions
- CSS Animations
- CSS Image Styling
- CSS Image Effects
- CSS Hover Overlays
- CSS Image Modal
- CSS Image Centering
- CSS Image Shapes
- CSS Buttons
- CSS Columns
- CSS Clip Path
- CSS Shapes
- CSS Scroll Snap
- CSS Architecture: BEM
- CSS Custom Properties