Name a component independently of its location
BEM stands for block, element and modifier. It is a naming convention, not a browser feature. A block names a component; an element names a part of that component; a modifier names a deliberate variation or state.
.course-card { padding: 1.25rem; border: 1px solid #cbd5e1; }
.course-card__title { margin: 0; font-size: 1.25rem; }
.course-card__action { margin-top: 1rem; }
.course-card--featured { border-color: #1d4ed8; background: #eff6ff; }
The modifier supplements the block class; it does not replace it. The title class expresses a component relationship without requiring a fragile selector such as main section div article h2.
Elements are conceptual parts
BEM element names do not need to reproduce every wrapper level. A deeply nested child can still be course-card__title. Avoid names such as block__wrapper__inner__title that encode the DOM tree and become obsolete after a markup refactor.
Keep modifiers specific
Use a modifier for a real variation such as featured or compact. Avoid vague names like --special2. For transient behavior, the project may use an explicit state class or data-state attribute; choose a consistent convention and keep styling synchronized with actual behavior.
Benefits and limits
BEM can reduce accidental selector collisions and keep specificity low. It does not automatically remove unused CSS, guarantee accessibility or prevent all cascade conflicts. A component can still misuse fixed heights or hide focus even with perfectly consistent names.
Practice
- Name a pricing-card block with title, price and action elements.
- Add a compact modifier that changes spacing without duplicating every declaration.
- Move the card into a sidebar and confirm its styles do not depend on the old page hierarchy.
- Remove a wrapper without renaming unrelated component elements.