Skip to content

BEM Naming With Sass

BEM (Block, Element, Modifier) is a naming convention that pairs extremely well with Sass's nesting and parent selector features. This lesson shows how to structure a component's SCSS using BEM, and why it avoids many of the pitfalls of deep descendant nesting.

What Is BEM, and Why Pair It With Sass?

BEM structures class names into three parts: a Block (the component, .card), an Element (a part of that block, .card__title), and a Modifier (a variation, .card--highlighted). Sass's & makes writing this naming convention concise without repeating the block name everywhere by hand.

.card {
  padding: 1rem;

  &__title {
    font-weight: 700;
  }

  &__body {
    color: #475569;
  }

  &--highlighted {
    border-left: 4px solid #2563eb;
  }
}

Compiles to four flat, low-specificity CSS rules: .card, .card__title, .card__body, and .card--highlighted.

BEM Naming Syntax

.block { }
.block__element { }
.block--modifier { }
.block__element--modifier { }
  • Blocks are standalone components: .card, .nav, .button.
  • Elements are parts of a block, joined with two underscores: .card__title.
  • Modifiers are variations, joined with two hyphens: .card--highlighted.
  • Element and modifier can combine: .card__title--large.

BEM With Sass Cheatsheet

How BEM's three parts map onto Sass's parent selector.

BEM Part SCSS With & Compiled Class
Block .card { ... } .card
Element &__title { ... } .card__title
Modifier &--highlighted { ... } .card--highlighted
Element + modifier &__title--large { ... } .card__title--large
Modified element &--dark &__title { ... } .card--dark .card__title

Why BEM Avoids Deep Nesting Problems

Instead of nesting elements many levels deep (which produces increasingly specific descendant selectors), BEM flattens the structure into single-class selectors. This keeps every rule at roughly the same, low specificity, making overrides far more predictable.

// Deep descendant nesting (higher, less predictable specificity)
.card .header .title { font-weight: 700; }

// BEM with & (flat, low, consistent specificity)
.card__title { font-weight: 700; }

Modifiers That Affect Child Elements

Sometimes a block-level modifier needs to change the style of one of its own elements. This is one of the few cases where a slightly deeper combination is appropriate, combining the block's modifier with an element selector.

.card {
  &--dark {
    background: #1e293b;
  }

  &--dark &__title {
    color: white;
  }
}

BEM Plus the 7-1 Pattern

BEM and the 7-1 architecture pattern combine naturally: each BEM block typically gets its own partial inside components/, named after the block itself, _card.scss containing the entire .card block, its elements, and its modifiers.

Common Mistakes

  • Nesting BEM elements inside each other unnecessarily, .card__header__title isn't standard BEM and adds needless specificity.
  • Mixing BEM naming with unrelated utility classes in a way that makes it unclear which class is the "source of truth" for a style.
  • Forgetting that a modifier changes a block's own appearance and isn't automatically inherited by that block's elements without an explicit combined selector.
  • Using single underscores or a single hyphen instead of BEM's standard double underscore (__) and double hyphen (--) separators.

Key Takeaways

  • BEM structures class names into Block, Element, and Modifier parts.
  • Sass's & makes writing BEM concise: &__element and &--modifier.
  • BEM keeps compiled selectors flat and consistently low-specificity, unlike deep descendant nesting.
  • BEM blocks map naturally onto individual component partials inside a 7-1-style components/ folder.

Pro Tip

Keep each BEM block's entire SCSS, its own styles, elements, and modifiers, inside one clearly named partial file, this makes it trivial to find, review, or eventually delete a component's styles as a single, self-contained unit.