Native CSS nesting (now baseline across all major browsers) lets you write component styles with nested selectors — the same ergonomics as Sass/Less BEM nesting — directly in plain CSS, without a build step. The browser resolves nested rules to flat selectors at parse time, and specificity works exactly as it would for the equivalent flat rule.
Problem: CSS BEM-style selectors like .card__title or .nav--dark .nav__link require long class names and stylesheet organisation discipline to avoid unintended specificity conflicts — a preprocessor like Sass is needed for nested syntax.
Solution: Use native CSS Nesting (now supported in all major browsers) — write .card { & .title { } &:hover { } } directly in CSS without a preprocessor. The & references the parent selector, and nested rules work with pseudo-classes, pseudo-elements, and media queries. WordPress's theme.json supports nested styles for blocks.
The examples below show BEM-style component nesting, combining nesting with pseudo-classes and pseudo-elements, nesting media queries inside selectors, and how to write a WordPress block stylesheet using only native CSS nesting.
/* ── 1. BEM component with native nesting ────────────────────────────────── */
.card {
border: 1px solid var(--border);
border-radius: 8px;
overflow: hidden;
/* __element */
& .card__image {
width: 100%;
aspect-ratio: 16 / 9;
object-fit: cover;
}
& .card__body {
padding: 1rem;
& .card__title {
font-size: 1.1rem;
text-wrap: balance;
margin-block-end: .5rem;
}
& .card__excerpt {
color: var(--text-muted);
text-wrap: pretty;
}
}
& .card__footer {
padding: .75rem 1rem;
background: var(--surface-2);
display: flex;
justify-content: space-between;
}
/* --modifier */
&.card--featured {
border-color: var(--accent);
box-shadow: 0 0 0 2px var(--accent);
}
/* pseudo-classes */
&:hover { box-shadow: var(--shadow-lg); }
&:focus-within { outline: 2px solid var(--accent); }
/* pseudo-element */
&::before {
content: '';
display: block;
height: 4px;
background: var(--accent);
}
}
/* ── 2. Nested media queries ────────────────────────────────────────────── */
.hero {
padding-block: 3rem;
font-size: 1rem;
@media (min-width: 768px) {
padding-block: 5rem;
font-size: 1.125rem;
}
@media (min-width: 1200px) {
padding-block: 8rem;
}
}
/* ── 3. WordPress block stylesheet using native nesting ───────────────────
file: blocks/my-block/style.css (no Sass needed) */
.wp-block-my-plugin-feature-card {
display: grid;
gap: 1rem;
& .feature-card__icon {
width: 3rem;
height: 3rem;
color: var(--wp--preset--color--accent, #0073aa);
}
& .feature-card__title {
font-size: var(--wp--preset--font-size--large);
text-wrap: balance;
}
&:where(.is-style-outlined) {
border: 2px solid currentColor;
padding: 1.5rem;
border-radius: 4px;
}
}
NOTE: Unlike Sass, native CSS nesting requires the nested selector to start with a valid CSS selector token or & — you cannot nest bare element names like h2 { } directly without prefixing with & h2 { }; the & is mandatory for descendant element selectors in native nesting.