🚀 LEVEL UP TO SENIOR:Unlock 500+ Advanced Practical Challenges & Exercises.
🎓 COURSERA PARTNER:Earn professional Google, Meta, and IBM certificates to supercharge your resume.
CSS MASTER CLASS /// VISUAL ENGINEERING /// LAYOUT DESIGN /// ANIMATION LAB /// CSS MASTER CLASS /// VISUAL ENGINEERING ///

BEM: Block, Element, Modifier

Master the Block, Element, Modifier naming formula, understand its flat-nesting rule for elements, and learn when its verbosity is worth the unambiguous clarity it provides.

Total XP: 0|💻 css XP: 0

Skill Matrix

UNLOCK NODES BY LEARNING NEW TAGS.

BEM Methodology

Block, Element, Modifier naming.


🚀 LEVEL UP TO SENIOR:Unlock 500+ Advanced Practical Challenges & Exercises.
🎓 COURSERA PARTNER:Earn professional Google, Meta, and IBM certificates to supercharge your resume.

BEM is the most widely adopted CSS naming convention because it's mechanical rather than subjective — given any component, there's exactly one correct way to name its parts, removing the debate that unstructured naming invites.

1The Three Parts, Precisely Defined

A Block is an independent, reusable component: .card. An Element is a part of that block with no standalone meaning, joined with a double underscore: .card__title. A Modifier is a variant or state of a block or element, joined with a double hyphen: .card--featured or .card__title--large.

The formula is deliberately mechanical: given any piece of UI, you name the containing block, then its parts as elements, then any variants as modifiers. There's rarely ambiguity about what to call something, which is precisely BEM's core value proposition over ad-hoc naming.

.card { } /* Block */
.card__title { } /* Element */
.card--featured { } /* Modifier */
localhost:3000
✓ Unambiguous NamingEvery class name self-describes its role: Block, Element, or Modifier — no need to inspect the CSS file to understand the relationship.

2Elements Are Always Flat, Never Nested Twice

A common early mistake is mirroring deep DOM nesting in the class name — .card__header__title for a title nested inside a header nested inside a card. Strict BEM rejects this: an element attaches directly to its block, always, regardless of how deep it sits in the actual markup.

The reasoning is architectural, not stylistic: elements exist to describe a *relationship to the block*, not a *position in the DOM tree*. .card__title is understandable and stable even if you later move the title out of a .card__header wrapper — the DOM structure changed, but the component relationship (title belongs to card) didn't.

/* Wrong: mirrors DOM nesting */
.card__header__title { }

/* Correct: flat, tied to the block */
.card__title { }
localhost:3000
⚠ Common MistakeNesting elements to match DOM depth couples the class name to markup structure — exactly what BEM's flat rule prevents.

3When BEM's Verbosity Is Actually Worth It

BEM class names are long, and that's a deliberate trade-off, not an oversight. On a small project with one contributor, the verbosity may not pay for itself. On a large team where developers frequently touch components they didn't write, the payoff is substantial: .card__title--featured tells any reader its exact scope and relationship instantly, without opening the stylesheet.

The pattern also plays exceptionally well with component-based frameworks, since a BEM block maps naturally onto a single component file — the naming convention and the code organization reinforce each other rather than fighting.

/* Readable at a glance, even out of context */
.pricing-card__cta--disabled { opacity: 0.5; }
localhost:3000
Reading the name alone:
Block: pricing-card
Element: cta
Modifier: disabled

4Step-by-Step Breakdown

Block__Element--Modifier. BEM (Block, Element, Modifier) turns component-based thinking into a strict, mechanical naming formula: every class name alone tells you exactly what it is and how it relates to everything around it, without needing to read any surrounding CSS or HTML nesting to understand it.

Block: The Standalone Component. A Block is a self-contained component that makes sense on its own: .card, .menu, .form. It never depends on being inside another block to be meaningful, and its name is a plain noun describing what it is, not where it lives.

Identifying Blocks. Which of these is correctly formatted as a BEM Block class name?

  • .card
  • .card__title
  • .card--large

Element: A Part That Only Makes Sense Inside Its Block. An Element is a piece of a block that has no independent meaning outside it, written as block__element. .card__title only makes sense as part of .card — it's never reused standalone, and critically, elements are never nested more than one level: there's no .card__title__text.

The Flat Element Rule. In strict BEM, why is .card__title__text considered incorrect?

  • It's simply too long a class name
  • BEM elements are always flat relative to their block — double-nesting elements isn't valid
  • It's actually correct BEM syntax

Modifier: A Variant Or State. A Modifier changes the appearance or state of a block or element, written as block--modifier or block__element--modifier. It's always applied alongside the base class, never alone — .card--featured still needs .card present on the same element.

Modifiers In Practice. In BEM, does .card--featured ever appear on an element without the .card class also present?

  • Yes, modifiers can fully replace the base class
  • No — modifiers are always applied together with their base block or element class
  • It depends on the specific project

BEM Fluency Achieved. You can now name any component using strict BEM syntax: a standalone Block, its flat Elements, and its Modifiers for variants and state. BEM's verbosity is the trade-off for its single biggest benefit — a class name alone tells you everything about a rule's scope and relationships, with zero ambiguity.

Target A BEM Element Class. BEM names an element's class as block__element — write a rule that targets it directly.

Level Up 🚀

Advanced cheat sheets, SEO tricks, and interview prep for this topic.

Browser Support

ChromeSupported

Fully supported.

FirefoxSupported

Fully supported.

SafariSupported

Fully supported.

EdgeSupported

Fully supported.

Accessibility (A11y)

1BEM Modifiers Should Reflect Visual State In Sync With ARIA State

When a `.button--disabled` modifier is applied, the corresponding `disabled` attribute or `aria-disabled` must be applied to the same element, since CSS classes alone communicate nothing to assistive technology.

2Predictable Naming Makes Accessibility Review Faster On Unfamiliar Components

A reviewer unfamiliar with a component can infer its structure purely from BEM class names, making it faster to spot missing focus states or ARIA attributes without first reverse-engineering the component's DOM.

SEO Implications

  • 1

    BEM's Flat Elements Keep Selectors Low-Specificity By Construction

    Because BEM classes are always single-class selectors by convention, they avoid the deep descendant chains that increase style-matching cost during layout and paint on large pages.

  • 2

    Consistent Naming Improves Automated CSS Tooling Accuracy

    Tools that detect unused CSS or generate documentation can parse BEM's mechanical Block__Element--Modifier structure far more reliably than free-form class names, indirectly supporting leaner shipped stylesheets.

Best Practices

Name The Block First, Then Derive Elements And Modifiers From It

Starting from the block keeps the naming grounded in the component's identity rather than accidentally mirroring DOM structure, which is the most common source of BEM naming mistakes.

Reserve BEM For Components, Not For Utility Classes

Utility classes like `.mt-4` intentionally break BEM's block-relationship model because they're meant to be atomic and reusable everywhere — mixing the two systems for the same class is a common source of confusion.

Frequent Bugs

THE BUG

An element class was renamed to match new DOM nesting, breaking every reference to it in JavaScript.

THE FIX

Elements should describe the block relationship, not DOM position — keep `.card__title` stable even if it moves to a different wrapper inside the card.

THE BUG

A modifier class is applied without its base block class, and none of the expected styles appear.

THE FIX

Modifiers only ever override specific properties; always apply the base block/element class alongside any modifier.

Real-World Examples

A Complete BEM Card Component

A pricing card component using the full Block, Element, Modifier structure for its featured-plan variant.

<div class="card card--featured">
  <h3 class="card__title">Pro Plan</h3>
  <button class="card__cta card__cta--primary">Subscribe</button>
</div>

Interview Prep

?Frequently Asked Questions

Pascual Vila

Pascual Vila

Frontend Instructor // Code Syllabus

Common Pitfalls & Errors

The Error //

Nesting BEM elements to mirror DOM depth

/* Wrong */ .card__header__title { } /* Correct */ .card__title { }

The Solution //

Keep elements flat and tied directly to their block, regardless of actual DOM nesting.

The Error //

Applying a modifier class without its base class

<!-- Wrong --> <div class="card--featured"> <!-- Correct --> <div class="card card--featured">

The Solution //

Always include the base block or element class alongside any modifier in the HTML.

Lesson Glossary

[01]Block

A standalone, reusable BEM component.

Code Preview
.card

[02]Element

A part of a block with no independent meaning.

Code Preview
.card__title

[03]Modifier

A variant or state of a block or element.

Code Preview
.card--featured

[04]BEM

Block, Element, Modifier — a mechanical CSS naming convention.

Code Preview
block__element--modifier

Continue Learning