CSS Nesting: How to Write Nested CSS Selectors
CSS Nesting lets you write selectors inside other style rules so related styles stay grouped together. It can make large stylesheets easier to read, especially when you are styling a component, a card, a menu, or a form with several related states and descendants.
Quick answer: CSS Nesting lets you place selectors inside another rule and reuse the parent selector with &. It is useful for organizing related styles, but you should still understand how it expands into normal CSS selectors.
Difficulty: Beginner
You'll understand this better if you know: basic CSS selectors, class names, and how descendant selectors work.
1. What Is CSS Nesting?
CSS Nesting is a way to write nested style rules inside a parent rule instead of repeating the parent selector over and over. The browser treats the nested rules as if they were written out as normal selectors.
- It groups related rules under one parent selector.
- It helps reduce repeated selector text.
- It works with descendant selectors, pseudo-classes, and nested state styles.
- It uses & when you want to refer to the parent selector directly.
In practice, nesting is a readability feature. It does not change what CSS can do; it changes how you organize the same styles.
2. Why CSS Nesting Matters
As stylesheets grow, related rules are often spread across many lines. Nesting helps keep a component’s styles together so you can understand them faster and update them with less searching.
It matters most when you are styling one UI section with several pieces, such as a product card with a title, image, button, hover state, and selected state. Instead of scanning a long file for related selectors, you can keep those rules in one place.
Nesting is especially useful when you work on design systems, reusable components, or pages with many repeated patterns. It is less helpful when your selectors are already short and flat or when grouping would hide important relationships.
3. Basic Syntax or Core Idea
At its simplest, nested CSS looks like a parent rule followed by child rules inside it. The browser expands the nested blocks into full selectors.
Minimal nested example
This example shows a parent class with a nested rule for its paragraph children.
.card {
padding: 1rem;
border: 1px solid #ccc;
p {
margin: 0;
}
}This is equivalent to writing .card p as a separate selector. The nested form keeps the paragraph rule visually attached to the card rule.
Using the parent selector with &
Use & when the nested selector needs to include the parent selector directly, such as for hover states or modifier classes.
.button {
background: black;
color: white;
&:hover {
background: dimgray;
}
}In this case, &:hover becomes .button:hover. Without &, the browser would treat the nested selector as a descendant selector instead.
4. Step-by-Step Examples
Example 1: Styling a card component
A card often has multiple related parts. Nesting keeps the title, text, and link styles under the same parent.
.card {
padding: 1rem;
background: white;
h2 {
margin: 0 0 0.5rem;
}
p {
line-height: 1.5;
}
& a {
color: royalblue;
}
}This structure makes it obvious that the heading, paragraph, and link belong to the card component. The last rule uses & so the selector becomes .card a.
Example 2: Hover and active states
Nesting is a natural fit for interactive states because the state belongs to the same element.
.tab {
padding: 0.5rem 1rem;
border: none;
background: #eee;
&:hover {
background: #ddd;
}
&.is-active {
background: black;
color: white;
}
}Here, hover and active styles stay close to the base tab rule. This is easier to scan than three separate selectors scattered through the file.
Example 3: Descendant selectors inside a section
Nested selectors can target children inside a layout section without repeating the section name every time.
.article {
max-width: 60ch;
h1 {
font-size: 2rem;
}
ul {
padding-left: 1.25rem;
}
li {
margin-bottom: 0.5rem;
}
}This works well when a section has a predictable internal structure. The nested rules are still normal CSS descendant selectors after expansion.
Example 4: Nested modifiers and subcomponents
You can nest further for variants, but keep the hierarchy readable. Use it when the relationship is real, not just to make selectors look shorter.
.alert {
padding: 1rem;
border-radius: 0.5rem;
&.alert--success {
background: #e7f7ea;
}
&.alert--error {
background: #fdeaea;
}
}This pattern is useful for component variants. It keeps the base style and variant styles together so the component is easier to maintain.
5. Practical Use Cases
CSS Nesting is most useful when styling related rules that belong to the same visual component or section.
- A product card with image, title, description, and buttons.
- A navigation menu with links, hover states, and active states.
- A form with labels, inputs, focus styles, and validation states.
- A blog article layout with headings, lists, and link styles inside one content container.
- A reusable alert, badge, or banner component with multiple variants.
It is usually less helpful for one-off utility styles or very small stylesheets where plain selectors stay clearer.
6. Common Mistakes
Mistake 1: Forgetting that a nested selector is usually a descendant selector
Beginners often expect a nested selector to target the parent element again, but plain nested selectors target descendants. That difference changes which elements are styled.
Problem: This rule styles only span elements inside .button, not the button element itself.
.button {
span {
font-weight: bold;
}
}Fix: Use & if you mean the button itself or one of its states.
.button {
& {
font-weight: bold;
}
}The corrected version works because & refers to the parent selector instead of creating a descendant relationship.
Mistake 2: Mixing nesting depth until the selector becomes hard to read
Deeply nested CSS can become harder to maintain than flat CSS. Even though nesting looks organized at first, too many levels can hide the actual selector path.
Problem: This nesting is technically valid, but it creates a selector chain that is difficult to understand and may encourage overly specific styles.
.page {
.sidebar {
.menu {
li {
a {
color: red;
}
}
}
}
}Fix: Keep nesting shallow and flatten selectors when the relationship is not directly component-based.
.sidebar {
background: #f7f7f7;
}
.sidebar .menu a {
color: red;
}The corrected version is easier to scan and reduces the chance of creating selectors that are too specific.
Mistake 3: Expecting nesting to behave the same in every browser version
CSS Nesting is a relatively new feature, so older browsers or older project environments may not support it fully. If the styles do not apply, the issue may be compatibility rather than syntax.
Problem: A stylesheet that uses nesting may appear to do nothing in browsers or tools that do not understand nested syntax.
.card {
h2 {
color: navy;
}
}Fix: Check browser support for your target audience and provide a flat fallback if needed.
.card h2 {
color: navy;
}
@supports (selector(.card { h2 { color: navy; } })) {
.card {
h2 {
color: navy;
}
}
}The fixed approach preserves support for older environments while still allowing nesting where it is available.
7. Best Practices
Practice 1: Nest only when the styles truly belong together
Use nesting for styles that are part of the same component or section. This keeps related rules grouped without turning the file into a maze of nested blocks.
.profile-card {
.avatar {
border-radius: 50%;
}
}This is better than nesting unrelated selectors just because they can be nested.
Practice 2: Use & for states, variants, and self-references
When the selector must refer to the parent element itself, & avoids ambiguity and makes intent clear.
.toggle {
&.is-open {
max-height: 20rem;
}
}This makes it obvious that the open state applies to the same element as the base rule.
Practice 3: Keep nesting shallow
Shallow nesting is easier to maintain and less likely to create selectors that are difficult to override later. A useful rule is to avoid nesting just because the feature is available.
.menu {
a {
text-decoration: none;
}
}A short selector path is usually enough for a small component like a menu.
8. Limitations and Edge Cases
- Nesting does not replace the need to understand the final expanded selector.
- Deep nesting can increase selector specificity and make overrides harder.
- Browser support may vary depending on the version your users run, so older environments may need a fallback.
- Not every selector should be nested; utility classes and global patterns are often clearer when written flat.
- When you nest compound selectors, it is easy to accidentally create a selector that is broader or narrower than intended.
One common surprise is that nesting can look like a preprocessor feature, but modern CSS nesting is part of CSS itself. That means you still need to think about how the browser interprets the selector, especially when using &.
9. Practical Mini Project
Let’s build a small newsletter signup card with nested styles. This keeps the card, heading, form, and button styles together in one component block.
.signup-card {
max-width: 28rem;
padding: 1.5rem;
border: 1px solid #ddd;
border-radius: 0.75rem;
background: #fff;
h2 {
margin-top: 0;
}
form {
display: grid;
gap: 0.75rem;
}
input {
padding: 0.75rem;
border: 1px solid #bbb;
border-radius: 0.5rem;
}
button {
padding: 0.75rem 1rem;
border: none;
border-radius: 0.5rem;
background: black;
color: white;
&:hover {
background: #333;
}
}
}This example is small enough to stay readable, but it still shows the main value of nesting: related styles are grouped in one place. The output is normal CSS selectors, just organized more clearly in the source.
10. Key Points
- CSS Nesting lets you write related selectors inside a parent rule.
- Plain nested selectors usually mean descendants, not the parent itself.
- Use & when the selector should include the parent selector directly.
- Shallow nesting is usually easier to maintain than deep nesting.
- Browser support matters, so check your target audience before relying on nesting alone.
11. Practice Exercise
Try rewriting a flat stylesheet into nested CSS for a simple product card.
- Create a .product-card rule with padding, border, and background.
- Inside it, nest styles for h3, p, and button.
- Add a hover state for the button using &:hover.
- Keep the nesting to no more than two levels deep.
Expected output: A component stylesheet where all product-card-related rules are grouped together and the hover state is written with &.
Hint: Start with the parent class, then add one nested block for each child element or state.
Solution:
.product-card {
padding: 1rem;
border: 1px solid #ddd;
background: white;
h3 {
margin-top: 0;
}
p {
color: #555;
}
button {
padding: 0.5rem 0.75rem;
border: none;
background: black;
color: white;
&:hover {
background: #333;
}
}
}This solution keeps the component organized while still producing standard CSS behavior.
12. Final Summary
CSS Nesting is a readability feature that helps you group related selectors under a parent rule. It is especially useful for components, sections, and state styles where the relationship between selectors is clear.
The most important idea is that nested selectors still follow normal CSS logic. A plain nested selector usually means a descendant selector, while & lets you reference the parent selector directly. If you understand that distinction, you can use nesting without getting surprised by the output.
For best results, keep nesting shallow, use it for real component relationships, and check browser support for the users you care about. If you want to go further, the next step is to practice translating nested rules back into flat selectors so you can always predict what the browser will apply.