CSS Nesting: Compound vs Descendant Selectors
Native CSS nesting uses the nesting selector (&) to
reference the parent rule, allowing developers to write more modular and
readable stylesheets. The key distinction between
&.active and & .active comes down to
whitespace: omitting the space creates a compound selector that targets
the parent element itself when it possesses an additional class, whereas
including a space creates a descendant selector that targets a child
element nested inside the parent.
The Role of the Nesting
Selector (&)
In native CSS nesting, the ampersand (&) represents
the parent selector list wrapped inside an :is()
pseudo-class. When you nest rules, the position of &
relative to other selectors determines how the final rule is resolved by
the browser's CSS engine.
Compound Selectors:
&.active
When there is no space between the ampersand and the class name, CSS treats the expression as a compound selector. This combines the parent selector and the new class on the same HTML element.
.button {
background-color: blue;
&.active {
background-color: green;
}
}This compiles conceptually to:
.button.active {
background-color: green;
}Under the CSS Nesting specification, the browser evaluates this as
:is(.button).active. It targets an element that matches
both .button and .active simultaneously:
<!-- Matches &.active -->
<button class="button active">Click Me</button>Descendant Selectors:
& .active
When a space is placed between the ampersand and the class name, the
whitespace acts as the descendant combinator. This specifies that the
rule should apply to an element with the class .active that
is located anywhere inside the parent element.
.button {
background-color: blue;
& .active {
color: yellow;
}
}This compiles conceptually to:
.button .active {
color: yellow;
}The browser evaluates this as :is(.button) .active. It
targets a nested descendant element rather than the parent element
itself:
<!-- The outer button matches .button; the inner span matches & .active -->
<button class="button">
Status: <span class="active">Online</span>
</button>Summary of Differences
&.active(No space): Modifies the parent element. Use this for state classes, theme variations, or conditional styles applied directly to the container (e.g.,.card.active,.nav-item.active).& .active(With space): Traverses the DOM tree to target children. Use this when the active state belongs to an inner element contained within the parent component (e.g., an active icon, indicator, or label inside a button).