tezvyn:

BEM: Scoped CSS Naming by Convention

AI-drafted, machine-checkedintermediate

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-form__input. A Modifier is a flag or variant and uses two dashes, as in search-form--compact or search-form__input--error. The rules are strict. You do not nest Elements; there is no block__elem1__elem2. 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-card__image, its title is media-card__title, and its metadata row is media-card__meta. 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-card__title--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.

Get five bites like this every day.

Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.