CSS Naming Conventions & BEM
As projects grow, CSS becomes unmaintainable without structure. BEM (Block Element Modifier) is the most popular naming convention — it creates predictable, self-documenting class names that prevent specificity conflicts. Other methodologies include OOCSS, SMACSS, and ITCSS.
35 min•By Priygop Team•Last updated: Feb 2026
BEM Naming Convention
- Block — Independent component: .card, .navbar, .modal. Standalone, reusable
- Element — Part of a block: .card__title, .card__body, .card__footer. Two underscores separate block and element
- Modifier — Variation: .card--featured, .btn--large, .btn--disabled. Two hyphens separate the modifier
- Never nest BEM selectors — .card .card__title is wrong. Use .card__title directly. Flat specificity
- OOCSS — Object-Oriented CSS. Separate structure from skin. .media (layout) + .media--dark (visual theme)
- SMACSS — Categorize CSS: Base, Layout, Module, State, Theme. Good for large teams
- ITCSS — Inverted Triangle: Settings → Tools → Generic → Elements → Objects → Components → Utilities
BEM Code Examples
Example
/* BEM naming in practice */
/* Block */
.card { background: white; border-radius: 12px; overflow: hidden; }
/* Elements (parts of card) */
.card__header { padding: 16px; border-bottom: 1px solid #eee; }
.card__title { font-size: 1.25rem; font-weight: 700; margin: 0; }
.card__body { padding: 16px; }
.card__footer { padding: 12px 16px; background: #f8f9fa; }
.card__image { width: 100%; height: 200px; object-fit: cover; }
/* Modifiers (variations) */
.card--featured { border: 2px solid var(--primary); }
.card--compact { border-radius: 8px; }
.card--compact .card__body { padding: 12px; }
.card--dark {
background: #1a1a2e;
color: white;
}
/* Button with BEM */
.btn { padding: 10px 20px; border: none; border-radius: 6px; cursor: pointer; }
.btn--primary { background: var(--primary); color: white; }
.btn--secondary { background: var(--secondary); color: white; }
.btn--large { padding: 14px 28px; font-size: 1.1rem; }
.btn--small { padding: 6px 14px; font-size: 0.85rem; }
.btn--disabled { opacity: 0.5; cursor: not-allowed; }
/* ❌ Anti-patterns to avoid */
/* .card .title { } — too generic, causes conflicts */
/* .card > div > p { } — fragile, breaks when HTML changes */
/* #main-card { } — IDs have too much specificity */