Skip to content
tezvyn:
Menu

BEM: Scoped CSS Naming by Convention

MediumHow cards are made

BEM is a naming convention that scopes CSS classes like postal addresses, preventing specificity wars in component systems. It shines in large codebases with many developers. The footgun is deep element nesting, which bloats markup into unreadable strings.

Why it exists

Before component-based front ends, CSS was global. A class named button or active could collide across features, forcing developers into nested selectors and unpredictable override battles. BEM was created to solve this namespace collision problem without requiring CSS-in-JS or build-step scoping. It imposes a human-readable naming contract that makes every class name globally unique by construction, directly addressing the root cause of style leaks.

The mental model

Think of a BEM class as a postal address. The Block is the building, a standalone entity like a card or a navbar. The Element is an apartment inside that building, such as a title or a button that has no meaning outside the card. The Modifier is a variant of either, like a disabled state or a dark theme, equivalent to painting the front door red. Because the address is complete, you never need to ask the postal system to guess which building the apartment belongs to, and you never need nested directions.

How it works

A Block is a top-level component and gets a class like search-form. An Element is a child piece and uses two underscores, as in search-forminput. A Modifier is a flag or variant and uses two dashes, as in search-form--compact or search-forminput--error. The rules are strict. You do not nest Elements; there is no blockelem1elem2. You do not use Element classes outside their Block context in the CSS, even if the HTML structure happens to nest. Selectors remain single classes, which keeps specificity uniformly low and makes overrides predictable.

When to use it

BEM pays off in large codebases maintained by multiple teams, especially when a design system must stay consistent across pages that do not share a JavaScript framework. It is also valuable in legacy projects where introducing CSS Modules or a CSS-in-JS library is politically or technically impossible. If you are writing plain CSS or preprocessor code and need a zero-dependency scoping discipline, BEM is the cheapest contract you can adopt.

When not to use it

Do not use BEM in a scoped styling environment where the build system already hashes classes, such as CSS Modules or most modern CSS-in-JS solutions, because the naming ceremony adds noise without solving a real problem. Also avoid it for tiny static sites with a single stylesheet; the verbosity is not worth the collision insurance. If your team cannot agree on what constitutes a Block versus an Element, the convention will fragment and become meaningless.

One canonical example

Consider a media card. The Block is media-card. Its image is media-cardimage, its title is media-cardtitle, and its metadata row is media-cardmeta. A featured variant of the card gets media-card--featured, which might change the layout or border. An error state on the title gets media-cardtitle--error. The HTML remains readable, the CSS stays flat, and a developer six months later can grep the codebase and know exactly which component owns every class without opening the stylesheet.

Interview question

In which scenario is adopting BEM the most appropriate scoping strategy?

  • a.When the team maintains a large plain-CSS legacy codebase across multiple teamsCorrect
  • b.When the site is a tiny static project with a single stylesheet
  • c.When the team needs to raise CSS specificity to prevent style overrides
  • d.When the project already uses CSS Modules to hash classes at build time
Why?

BEM is explicitly designed for large plain-CSS codebases where introducing a build step is not feasible, using naming conventions to guarantee unique scopes. It is unnecessary when classes are already hashed by CSS Modules and too verbose for tiny sites, and it actually keeps specificity low rather than raising it.

Just read this? Test yourself on what you have been reading.

Put your scrolling time to good use

Learn one idea, try a quiz and save useful cards for revision. Tezvyn makes it easy to learn and stay current in your tech field, a few minutes at a time.

The iPhone app is on the way

We are building it. Until it lands, nothing here is held back from you: every interview card, your saved cards, streaks and the job board all work in Safari, plus hundreds of free practice quizzes of thirty questions each. Sign in and it all carries over to the app the day it arrives.

Want it as an icon? Tap Share at the bottom of Safari, then Add to Home Screen. It opens full screen and the cards you have read stay available offline.

Get it on Google PlayiPhone app coming soon

We are hiring for this. Open roles that interview on css — each one lists the topics its interview covers.

See open roles