The CSS Nesting Selector: A Complete Guide

Master the ampersand selector (&) for modular, maintainable stylesheets. Learn syntax variations, compound selectors, and modern web development best practices.

What is CSS Nesting?

CSS nesting represents one of the most significant additions to the stylesheet language in recent years. What was once the exclusive domain of preprocessors like Sass and Less is now natively supported in browsers, enabling developers to write more modular, maintainable stylesheets without any build step required. At the heart of this feature lies the ampersand selector (&), a powerful tool that gives developers precise control over how selectors are combined and extended.

Unlike preprocessor nesting, which is compiled before reaching the browser, native CSS nesting is parsed directly by the browser's CSS engine, resulting in identical behavior across all supporting browsers. This approach reduces selector repetition, groups related styles together, and makes stylesheets easier to read and maintain.

The CSS nesting module, defined in the W3C CSS Nesting Module Level 1 specification, introduces a new way of organizing stylesheet rules that aligns with how developers naturally think about component hierarchies. When you nest a style rule inside another, the browser automatically handles the selector combination, either implicitly adding a descendant combinator or using your explicit & selector to create the exact selector structure you intend.

Key benefits of native CSS nesting:

  • Native browser support eliminates build step requirements
  • Mirrors HTML structure for intuitive stylesheet organization
  • Reduces selector repetition and file size
  • Parsed directly by browser CSS engine
  • Works identically across all supporting browsers

Browser Support and Compatibility

CSS nesting has achieved broad browser support across all major browsers. Chrome and Edge added support starting with version 112, Firefox implemented the feature in version 117, and Safari support arrived in version 17.2 Chrome's browser support documentation. This broad adoption means that CSS nesting can now be used in production websites with minimal concern about compatibility issues for the vast majority of users.

For projects that need to support older browsers without native nesting support, PostCSS with the postcss-nesting plugin can transpile nested CSS into standard CSS that works in all browsers. This approach allows developers to write modern nested CSS while maintaining backward compatibility.

Adopting CSS nesting as part of your web development workflow can significantly improve code organization and maintainability, especially when combined with other modern CSS features like custom properties and container queries.

The Ampersand Selector: Your Key to Control

The ampersand selector (&) is the cornerstone of CSS nesting, giving developers explicit control over how parent and child selectors combine. When used in a nested rule, the & represents the parent selector, allowing you to create compound selectors, add pseudo-classes, and manipulate the final selector in ways that wouldn't be possible with implicit nesting alone Frontend Masters' guide on the ampersand selector.

At its most basic, the & selector simply represents the parent selector in the generated CSS. Writing .parent { & .child { color: red; } } produces the same result as .parent .child { color: red; }. The explicit use of & makes the relationship clear and provides a mental model that mirrors how the selector will be interpreted by the browser. This clarity becomes especially valuable in complex stylesheets where multiple levels of nesting make implicit relationships harder to track.

Using & for Pseudo-Classes and Pseudo-Elements

One of the most common use cases for the & selector is adding pseudo-classes to parent elements. Consider a button that changes appearance on hover. With the & selector, you can write hover, focus, and other states directly within the parent rule, keeping all button-related styles together while clearly expressing the relationship between the base style and the interactive state.

.button {
 background: blue;
 
 &:hover {
 background: darkblue;
 }
 
 &:focus {
 outline: 2px solid gold;
 }
 
 &:active {
 transform: translateY(1px);
 }
}

Generates: .button:hover, .button:focus, .button:active

The same approach works for pseudo-elements like ::before, ::after, and ::first-line. This pattern is particularly useful for decorative elements that are logically connected to their parent elements but require pseudo-element markup to achieve the desired visual effect.

Combining Classes and Attributes

The & selector truly shines when you need to combine multiple selectors on the same element. Native CSS nesting has a specific behavior: when you write a nested selector without &, the browser automatically adds a descendant combinator (a space) between the parent and child selectors. This behavior affects how compound selectors work.

For example, writing .card { .featured { } } creates .card .featured, targeting elements with class "featured" that are descendants of elements with class "card". However, writing .card { &.featured { } } creates .card.featureed, targeting elements that have both classes simultaneously. The difference is significant and demonstrates why understanding & is essential for correct selector construction.

.card {
 padding: 1rem;
 
 &.featured {
 border: 2px solid gold;
 }
 
 &.compact {
 padding: 0.5rem;
 }
 
 &[data-active="true"] {
 opacity: 1;
 }
}

Generates: .card.featureed, .card.compact, .card[data-active="true"]

Understanding these selector combinations is essential for writing clean, efficient CSS. When you're building component libraries or design systems, mastering the & selector helps you create maintainable styles that scale across your project.

Without & symbol - Browser adds descendant combinator automatically

.card {
 .card-title {
 font-weight: bold;
 }
 
 .card-body {
 padding: 1rem;
 }
}

Generates: .card .card-title, .card .card-body (descendant selectors)

Implicit nesting occurs when you write a nested selector without the & symbol. The browser automatically inserts a descendant combinator between the parent and child selectors. This approach is intuitive for targeting child elements that are structurally related to their parents, making it ideal for semantic HTML structures where the relationship is already clear.

Implicit nesting keeps your stylesheet organized by component while generating the standard descendant selector you need. It works well for most child element targeting scenarios where you want to select descendants at any depth.

Compound Selectors: When & Becomes Required

Compound selectors are selectors that join multiple simple selectors without any combinator characters. For example, .button.primary is a compound selector targeting elements with both "button" and "primary" classes MDN Web Docs' compound selector documentation. Understanding how compound selectors work with nesting is crucial because native CSS nesting handles them differently than you might expect from preprocessor experience.

Why & Is Required

When you write a nested selector without &, the browser treats it as a descendant selector by inserting a space. This behavior affects compound selectors because the space changes the selector's meaning.

Without &:

.card { .featured { } }
// Generates: .card .featured (descendant)

With &:

.card { &.featured { } }
// Generates: .card.featureed (compound)

The difference is significant - the first targets descendants, the second targets elements with both classes simultaneously.

This requirement might surprise developers familiar with Sass or Less nesting, where compound selectors often work without explicit & usage. The difference stems from how preprocessors handle selector combination versus how native CSS nesting is specified to work. Native CSS nesting prioritizes predictable behavior: without explicit &, the browser assumes you want a descendant relationship and adds a space accordingly.

Real-World Component Examples

Consider a card component with variant classes. The base card might have shared styles, while variants like "featured" or "compact" add specific modifications. Using compound selectors with &, you can write this pattern cleanly:

.card {
 padding: 1rem;
 border-radius: 8px;
 
 /* Variant modifiers - & IS required */
 &.featured {
 border: 2px solid gold;
 box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
 }
 
 &.compact {
 padding: 0.5rem;
 border-radius: 4px;
 }
 
 &.highlighted {
 background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
 color: white;
 }
 
 /* Size modifiers */
 &.large {
 padding: 1.5rem;
 font-size: 1.125rem;
 }
 
 &.small {
 padding: 0.5rem;
 font-size: 0.875rem;
 }
}

This generates .card, .card.featureed, .card.compact, .card.highlighted, .card.large, and .card.small selectors, each targeting the appropriate elements with efficient compound selectors.

For teams working on large-scale applications, mastering compound selectors through CSS nesting can improve both code quality and page performance by reducing selector complexity.

Nesting Media Queries

One of the most powerful applications of CSS nesting is the ability to nest @media queries and other at-rules directly within their relevant selectors Chrome's @media nesting guide. This approach keeps responsive styles co-located with the base styles they modify, eliminating the need to scroll through separate sections of your stylesheet to understand how a component responds at different viewport sizes.

Responsive Component Example

Traditional CSS organization often separates responsive styles into distinct blocks at the end of a stylesheet or in separate files. While this separation has its merits, it can make maintenance harder when you need to understand how a component's appearance changes across breakpoints. Nested @media queries solve this problem by keeping all relevant styles together.

.card {
 padding: 1rem;
 display: flex;
 flex-direction: column;
 gap: 1rem;
 
 @media (min-width: 768px) {
 padding: 2rem;
 display: grid;
 grid-template-columns: 1fr 2fr;
 gap: 2rem;
 }
 
 @media (min-width: 1024px) {
 max-width: 1200px;
 margin: 0 auto;
 
 &.featured {
 border: 2px solid gold;
 padding: 2.5rem;
 }
 }
}

Benefits of this approach:

  • All card styles in one location
  • Easy to see how component responds at different breakpoints
  • No scrolling between base styles and responsive modifications
  • Clear relationship between responsive states and variants

When & Is Needed in @media Blocks

Within nested @media blocks, the & selector becomes important when you need to modify the parent selector conditionally or create compound selectors within the responsive context. Without &, the @media block affects only the nested selectors directly inside it, not the parent selector itself.

.nav {
 display: flex;
 flex-direction: column;
 gap: 0.5rem;
 
 @media (min-width: 768px) {
 flex-direction: row;
 justify-content: space-between;
 
 &.expanded {
 display: grid;
 grid-template-columns: repeat(4, 1fr);
 gap: 1.5rem;
 }
 
 &.centered {
 justify-content: center;
 }
 }
}

The & in &.expanded ensures the class combination applies within the media query context, generating @media (min-width: 768px) { .nav.expanded { } }. Without &, you'd be creating a descendant selector .nav .expanded which would target different elements entirely.

Implementing responsive design patterns like nested media queries is a core skill in modern web development. When done correctly, it creates seamless experiences across all device sizes while keeping your codebase maintainable.

Best Practices for CSS Nesting

Keep Nesting Shallow

Limit nesting to 2-3 levels deep. Deep nesting creates hard-to-maintain selectors and tight HTML coupling. Consider flattening deeply nested selectors or using utility classes instead.

Use & for Clarity

Even when implicit nesting would work, explicit & improves readability and shows intentional selector construction. It acts as documentation for future maintainers.

Organize by Component

Group styles by component, not by selector type. Nesting naturally supports component-based organization, keeping all related styles together.

Test Generated Output

Verify the CSS your nesting generates matches expectations. Browser Dev Tools show resolved selectors and help debug nesting issues.

CSS Nesting vs Sass Nesting
FeatureCSS NestingSass Nesting
Selector combinationRequires explicit & for compoundsImplicit with descendant combinator
ConcatenationNot supported with &-suffixSupported with &-suffix for BEM patterns
Build stepNone required (native browser feature)Compilation required (Sass processor)
Browser supportChrome 112+, Firefox 117+, Safari 17.2+All browsers via compiled CSS
& meaningSelector referenceString concatenation or selector reference
Pseudo-class nestingNative supportSupported via preprocessing
@media nestingNative support within selectorsSupported via preprocessing

Conclusion

CSS nesting and the ampersand selector (&) provide powerful capabilities for organizing stylesheets in modern web development. Key takeaways:

  1. The & selector gives you control - Use it for compound selectors, pseudo-classes, and explicit selector construction
  2. Implicit vs explicit nesting - Without &, browser adds descendant combinator; with &, you control the exact combination
  3. & is required for compound selectors - Writing .card { .featured { } } creates .card .featured, not .card.featured
  4. Keep nesting shallow - 2-3 levels maximum for maintainable code and avoid specificity issues
  5. No concatenation - Unlike Sass, native CSS doesn't support .parent { &-child { } } - you must write the full selector

For modern web development with Next.js and similar frameworks, CSS nesting represents a significant step forward in developer experience. It enables cleaner, more expressive stylesheets without requiring build tools or preprocessor dependencies Chrome's CSS nesting developer guide. Combined with other modern CSS features like custom properties, logical properties, and container queries, nesting helps create maintainable stylesheets that scale with project complexity.

Performance benefits also emerge from using native CSS features. Without preprocessor compilation, there's no additional build step required for CSS processing. The styles you write work directly in the browser, making development faster and debugging simpler. As browser support continues to grow, CSS nesting will remain a valuable tool for creating professional-grade stylesheets that serve both developer experience and end-user performance.

Ready to level up your CSS? Our web development services team specializes in modern CSS architecture and can help you implement efficient styling strategies for your projects.

Frequently Asked Questions

Sources

  1. MDN Web Docs: Using CSS Nesting - The authoritative source on CSS nesting, covering basic syntax, the ampersand selector, compound selectors, and browser parsing behavior.

  2. Chrome for Developers: CSS Nesting - Official Chrome documentation with interactive examples, browser support details, and guidance on nesting @media queries.

  3. Frontend Masters: Three Approaches to the Ampersand Selector - Comprehensive tutorial covering three use cases for & (linked class names, parent selectors, recurring selectors) and key differences between vanilla CSS and preprocessor behavior.

  4. W3C CSS Nesting Module Level 1 - Official specification details on nesting selector behavior and rules.