ReviseAlgo Logo

Modern CSS

BEM

Master BEM (Block, Element, Modifier) naming conventions, covering class structures, flat specificity, and modular stylesheet design.

Last Updated: July 15, 2026 • 10 min read

1. Learning Objectives

In this lesson, you will master CSS architecture using the BEM methodology. By the end of this topic, you will be able to:

  • Identify BEM components: Blocks, Elements, and Modifiers.
  • Write standard BEM class names using double underscore (__) and double hyphen (--) separators.
  • Explain the specificity benefits of BEM flat selector structures.
  • Prevent nested BEM element name chains (like block__elem1__elem2).
  • Build modular, reusable component styles.

2. Overview

BEM (Block, Element, Modifier) is a popular naming convention for writing modular, reusable, and maintainable CSS. By organizing classes into independent components, BEM prevents selector collision bugs, simplifies stylesheet architectures, and ensures a flat specificity structure that is easy to debug.

3. Why This Topic Matters

Unstructured CSS class naming leads to style collisions and high specificity requirements in large codebases:

  • Selector Collision bugs: If you use generic class names (like .title or .button) across different components, styles from one component can bleed into another, causing visual bugs. BEM scopes styles to unique component blocks.
  • Specificity Wars: Deeply nested selectors (e.g. .sidebar .card ul li a) make styles difficult to override later. BEM uses flat, single-class selectors (specificity score: 10), making overrides easy.

4. Real-World Analogy

Think of BEM naming rules like **labeling car parts inside a workshop database**:

  • Block (The Car): A standalone component that makes sense on its own (e.g. car).
  • Element (The Wheel): A part of the block that cannot exist independently outside of it (e.g. car__wheel).
  • Modifier (The Winter Tire): A styling variation that changes the appearance or state of a block or element (e.g. car__wheel--winter).

5. Core Concepts

BEM divides selectors into three categories:

  • Block: A standalone, reusable component (e.g. .menu, .card).
  • Element: A nested part of a block that has no standalone meaning (e.g. .menu__item, .card__title). Element names are separated from block names by a double underscore (__).
  • Modifier: A flag that defines a variation in appearance, size, or state (e.g. .menu--dark, .card__title--featured). Modifier names are separated by a double hyphen (--).
BEM Class Type Category Visual Layout Role
.card Block The main component container block.
.card__button Element A button element scoped inside the card block.
.card__button--disabled Modifier A styling modifier representing a disabled button state.

6. Syntax & API Reference

Below is a standard HTML and CSS BEM structure for a component card:

7. Visual Diagram

This diagram displays BEM component nesting structure:

8. Live Example — Full Working Code

A sample HTML document showcasing styled BEM components and modifier state variations:

9. Interactive Playground

Try It Yourself Challenges:

  1. Add a new modifier class (e.g. .info-card--dark) to support dark background card layouts.
  2. Test what happens if you apply an element modifier class (e.g. .info-card__action-btn--primary) without the base button class. (Note: Modifiers should only add styles, they require the base class to establish core properties).

10. Common Mistakes

Mistake Why it happens Wrong Correct
Creating nested element chains Nesting element names to match deep HTML hierarchies, resulting in long class names (e.g. block__elem1__elem2). Element names should only describe the parent block relationship. .card__body__list__item .card__item (keep names flat relative to the block)
Applying modifiers alone Using modifier classes in HTML without the base class, causing the element to miss core styles. <button class="btn--active"> <button class="btn btn--active">

11. Best Practices

  • Keep element names flat: Element names should only represent their relationship to the parent block (e.g. .block__item), avoiding long nested chains (like .block__body__list__item).
  • Always pair modifiers with base classes: Modifiers should only add style variations (like color or border changes). Always pair them with the base component class (e.g. class="btn btn--primary") which establishes core layouts.
  • Keep stylesheets flat to avoid specificity issues: Avoid nesting selectors inside BEM stylesheets to keep specificity scores low and make style overrides easy to manage.
  • Avoid styling HTML tags directly: Style components using BEM classes rather than targeting HTML tags directly to prevent style bleed.

12. Browser Compatibility

Feature Chrome Firefox Safari Edge
BEM Class Selector naming support Supported Supported Supported Supported

13. Interview Questions

🟢 Q1: Why does BEM recommend against creating nested element chains like `.card__body__list__item`?

Answer: Nested element chains couple classes too tightly to the HTML structure. If you decide to change the layout (for example, removing the wrapper card body container), you are forced to rename all class files inside the component markup. Keeping class names flat (e.g. .card__item) makes it easier to update the layout without renaming classes.

14. Debugging Exercise

Identify BEM naming violations and fix the markup and CSS configurations:

View Solution

Diagnosis:
1. menu__body__list-item is a nested element chain violation.
2. menu-item--active is an active modifier used alone without its base class reference, and it misses correct element naming connection (should build off menu__item).

Fixed HTML & CSS:

15. Practice Exercises

Exercise 1: BEM Accordion Component

Build an accordion component. Write BEM classes for the parent container (block), header bar and body panel (elements), and open state changes (modifiers).

16. Scenario-Based Challenge

The Legacy Selector Refactoring Challenge:

A checkout dashboard stylesheet contains deeply nested selector rules (like .main .form div input[type="text"]). Styling updates are difficult because of high specificity. Propose an implementation plan using BEM naming conventions to refactor these styles into flat selectors.

17. Quick Quiz

Q1: Which character separator is standard for identifying BEM elements?

A) double hyphen (--)

B) single underscore (_)

C) double underscore (__)

Answer: C — Double underscores (__) are used to separate block names from element names.

18. Summary & Key Takeaways

  • • BEM organizes styles into modular components, preventing class name collisions.
  • • Keep element names flat relative to the block to make stylesheets easy to maintain.

19. Cheat Sheet

Selector Component Class Type
.block__element--modifier Full BEM naming structure representing a modified element within a block.