SMACSS
SMACSS — Scalable and Modular Architecture for CSS, created by Jonathan Snook — is a way of organizing a stylesheet by sorting every rule into one of five categories. Unlike BEM, it doesn't prescribe a specific class-naming syntax; instead it's a set of guidelines for deciding where a rule belongs and how specific or reusable it's allowed to be based on that category.
The five categories
Category | Description | Typical selectors |
|---|---|---|
Base | Default element styles with no class needed — resets, typography defaults | Element selectors: body, a, h1, ul |
Layout | Major structural regions of a page — grids, containers, headers/footers | IDs or classes, often prefixed l- or layout- |
Module | Reusable, discrete UI components — cards, nav menus, buttons | Classes, one per module, e.g. .card, .nav |
State | A state that overrides other styles depending on condition or JS — is-active, is-hidden | Classes prefixed is- or has-, sometimes with !important |
Theme | Visual styling that can be swapped out — colors, borders, backgrounds for a specific theme | Classes, often layered on top of module styles |
A worked example across categories
/* Base — no class, applies to every <a> on the site */
a {
color: #0066cc;
text-decoration: none;
}
/* Layout — a major page region */
.l-sidebar {
width: 280px;
float: left;
}
/* Module — a reusable, self-contained component */
.nav {
list-style: none;
padding: 0;
}
.nav__item {
padding: 0.5rem 1rem;
}
/* State — describes a condition, usually toggled by JS */
.nav__item.is-active {
background: #eef4ff;
font-weight: 600;
}
/* Theme — swappable visual treatment layered over the module */
.theme-dark .nav__item {
color: #f0f0f0;
background: #1a1a1a;
}The point of separating these isn't aesthetic — it's about setting different expectations for each category. Base styles should be low-specificity and rarely overridden. Module styles should be self-contained and safely reusable anywhere. State classes are expected to override module styles and are allowed slightly higher specificity for that reason. Knowing which bucket a rule falls into tells you how it's supposed to behave in the cascade before you even read its declarations.