Table of Contents
- Understanding Nested Styles in CSS
- 1.1 The Problem with Flat CSS
- 1.2 What Are Nested Styles?
- 1.3 Vanilla CSS Nesting (Modern Update)
- What Are CSS Preprocessors?
- 2.1 Why Use Preprocessors?
- 2.2 Introduction to Sass and Less
- Nested Styles in Sass
- 3.1 Installing Sass
- 3.2 Basic Nesting Syntax
- 3.3 The Parent Selector (
&) - 3.4 Nested Media Queries
- 3.5 Nested Properties
- Nested Styles in Less
- 4.1 Installing Less
- 4.2 Basic Nesting Syntax
- 4.3 Parent Selector Usage
- 4.4 Media Query Nesting in Less
- Sass vs. Less: Nesting Comparison
- Best Practices for Nested Styles
- Conclusion
- References
1. Understanding Nested Styles in CSS
1.1 The Problem with Flat CSS
Vanilla CSS is “flat” by design—each rule targets elements with a global selector, and there’s no built-in way to group styles by parent context. For example, styling a navigation menu might require:
/* Flat CSS: Repetitive parent selectors */
nav { padding: 1rem; }
nav ul { list-style: none; margin: 0; }
nav ul li { display: inline-block; margin: 0 0.5rem; }
nav ul li a { color: #333; text-decoration: none; }
nav ul li a:hover { color: #007bff; text-decoration: underline; }
Here, nav ul li is repeated to target a and a:hover, cluttering the code and making it hard to update (e.g., changing nav to header-nav requires editing all instances).
1.2 What Are Nested Styles?
Nested styles let you write CSS rules inside other rules, mirroring the nested structure of your HTML. Instead of repeating parent selectors, you nest child styles under their parent, making code more intuitive and maintainable.
For example, the navigation styles above could be rewritten with nesting as:
/* Nested syntax (Sass/Less) */
nav {
padding: 1rem;
ul {
list-style: none;
margin: 0;
li {
display: inline-block;
margin: 0 0.5rem;
a {
color: #333;
text-decoration: none;
&:hover {
color: #007bff;
text-decoration: underline;
}
}
}
}
}
This reads like a hierarchy, just like the HTML it styles: nav → ul → li → a.
1.3 Vanilla CSS Nesting (Modern Update)
In 2022, browsers began supporting native CSS nesting (via the CSS Nesting Module), eliminating the need for preprocessors for basic nesting. The syntax is similar to preprocessors:
/* Vanilla CSS nesting (supported in modern browsers) */
nav {
padding: 1rem;
ul {
list-style: none;
margin: 0;
li {
display: inline-block;
margin: 0 0.5rem;
a {
color: #333;
text-decoration: none;
&:hover { /* & works in vanilla CSS too! */
color: #007bff;
text-decoration: underline;
}
}
}
}
}
While native nesting is a step forward, preprocessors like Sass and Less still offer superior features (variables, mixins, modules) that work seamlessly with nesting. For complex projects, preprocessors remain the gold standard.
2. What Are CSS Preprocessors?
2.1 Why Use Preprocessors?
CSS preprocessors are scripting languages that compile into vanilla CSS. They add features like:
- Variables: Store reusable values (colors, spacing).
- Nesting: Group styles by parent context.
- Mixins: Reuse blocks of CSS with parameters.
- Inheritance: Extend styles from one selector to another.
- Modularity: Split code into smaller files (partials).
These features make CSS more scalable, maintainable, and fun to write!
2.2 Introduction to Sass and Less
- Sass: Launched in 2006, Sass is the most popular preprocessor. It has two syntaxes:
.scss(CSS-like, with curly braces) and.sass(indentation-based). We’ll use.scsshere for familiarity. - Less: Created in 2009, Less is lighter and more CSS-like than Sass. It uses
.lessfiles and prioritizes simplicity.
3. Nested Styles in Sass
3.1 Installing Sass
Sass is compiled to CSS using tools like dart-sass (the official implementation). Install it via npm:
npm install -g sass # Global install
Compile .scss to .css with:
sass input.scss output.css # One-time compile
sass --watch input.scss:output.css # Watch for changes
3.2 Basic Nesting Syntax
Sass nesting mimics HTML structure. Child selectors are indented inside their parent rule, eliminating repetitive parent selectors.
Example: Styling a Card Component
/* Sass (.scss) */
.card {
background: white;
border-radius: 8px;
padding: 2rem;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
/* Nested child selector */
.card-title {
font-size: 1.5rem;
color: #2d3748;
margin: 0 0 1rem 0;
}
/* Nested grandchild selector */
.card-body p {
color: #4a5568;
line-height: 1.6;
}
}
Compiled CSS Output:
/* Compiled CSS */
.card {
background: white;
border-radius: 8px;
padding: 2rem;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
.card .card-title {
font-size: 1.5rem;
color: #2d3748;
margin: 0 0 1rem 0;
}
.card .card-body p {
color: #4a5568;
line-height: 1.6;
}
3.3 The Parent Selector (&)
The & symbol in Sass refers to the parent selector. Use it to target pseudo-classes, pseudo-elements, or modify the parent itself.
Example: Hover and Active States
/* Sass (.scss) */
.btn {
padding: 0.5rem 1rem;
border: none;
cursor: pointer;
/* & = .btn */
&:hover {
opacity: 0.9;
}
&:active {
transform: scale(0.98);
}
/* Modify the parent: .btn--primary */
&--primary {
background: #007bff;
color: white;
}
}
Compiled CSS:
.btn {
padding: 0.5rem 1rem;
border: none;
cursor: pointer;
}
.btn:hover {
opacity: 0.9;
}
.btn:active {
transform: scale(0.98);
}
.btn--primary {
background: #007bff;
color: white;
}
3.4 Nested Media Queries
Sass lets you nest media queries inside selectors, keeping responsive styles close to their base styles (no more scrolling to the bottom of the file!).
Example: Responsive Card
/* Sass (.scss) */
.card {
width: 100%; /* Mobile-first */
@media (min-width: 768px) {
width: 50%; /* Tablet: 2 cards per row */
}
@media (min-width: 1200px) {
width: 33.33%; /* Desktop: 3 cards per row */
}
}
Compiled CSS:
.card {
width: 100%;
}
@media (min-width: 768px) {
.card {
width: 50%;
}
}
@media (min-width: 1200px) {
.card {
width: 33.33%;
}
}
3.5 Nested Properties
Sass lets you nest CSS properties that share a common prefix (e.g., font-, margin-), reducing repetition.
Example: Font Properties
/* Sass (.scss) */
.heading {
font: {
family: "Arial", sans-serif;
size: 2rem;
weight: bold;
}
margin: {
top: 1rem;
bottom: 0.5rem;
}
}
Compiled CSS:
.heading {
font-family: "Arial", sans-serif;
font-size: 2rem;
font-weight: bold;
margin-top: 1rem;
margin-bottom: 0.5rem;
}
4. Nested Styles in Less
4.1 Installing Less
Less can be compiled via lessc (the official compiler). Install it via npm:
npm install -g less # Global install
Compile .less to .css with:
lessc input.less output.css # One-time compile
4.2 Basic Nesting Syntax
Less nesting works similarly to Sass, with child selectors indented inside parents.
Example: Styling a Navigation Menu
/* Less (.less) */
nav {
background: #333;
padding: 1rem;
ul {
list-style: none;
margin: 0;
padding: 0;
li {
display: inline-block;
margin: 0 0.5rem;
a {
color: white;
text-decoration: none;
}
}
}
}
Compiled CSS:
nav {
background: #333;
padding: 1rem;
}
nav ul {
list-style: none;
margin: 0;
padding: 0;
}
nav ul li {
display: inline-block;
margin: 0 0.5rem;
}
nav ul li a {
color: white;
text-decoration: none;
}
4.3 Parent Selector Usage
Like Sass, Less uses & to reference the parent selector.
Example: Pseudo-Classes and Modifiers
/* Less (.less) */
.btn {
padding: 0.5rem 1rem;
border: none;
&:hover {
background: #eee;
}
&--danger {
background: #dc3545;
color: white;
}
}
Compiled CSS:
.btn {
padding: 0.5rem 1rem;
border: none;
}
.btn:hover {
background: #eee;
}
.btn--danger {
background: #dc3545;
color: white;
}
4.4 Media Query Nesting in Less
Less also supports nested media queries, keeping responsive styles localized.
Example: Responsive Button
/* Less (.less) */
.btn {
padding: 0.5rem 1rem;
@media (min-width: 768px) {
padding: 0.75rem 1.5rem; /* Larger padding on desktop */
}
}
Compiled CSS:
.btn {
padding: 0.5rem 1rem;
}
@media (min-width: 768px) {
.btn {
padding: 0.75rem 1.5rem;
}
}
5. Sass vs. Less: Nesting Comparison
| Feature | Sass | Less |
|---|---|---|
| Basic Nesting | Identical syntax (indent child selectors). | Identical syntax. |
| Parent Selector | Uses & for pseudo-classes/modifiers. | Uses & (same behavior). |
| Media Query Nesting | Supports nesting inside selectors. | Supports nesting inside selectors. |
| Nested Properties | Supports (e.g., font: { ... }). | Limited support (no official nested properties). |
| Error Handling | Robust (clear error messages). | Less detailed errors. |
| Ecosystem | Larger community, more tools/plugins. | Smaller community, simpler tooling. |
Verdict: For most projects, Sass is more powerful (thanks to nested properties, modules, and better tooling). Less is ideal for simpler use cases where minimalism is preferred.
6. Best Practices for Nested Styles
Nesting is powerful, but overuse leads to messy, overly specific CSS. Follow these rules:
✅ Avoid Over-Nesting
Limit nesting to 3 levels max. Deep nesting creates overly specific selectors (e.g., header nav ul li a) that are hard to override and bloat compiled CSS.
Bad:
/* Over-nested: Too specific! */
.header {
.nav {
ul {
li {
a {
color: blue;
}
}
}
}
}
Good:
/* Shallow nesting */
.header-nav {
ul {
list-style: none;
}
li {
display: inline;
}
a {
color: blue;
}
}
✅ Use & Judiciously
Reserve & for pseudo-classes (&:hover) and modifiers (&--primary). Avoid using it to create overly complex selectors.
✅ Combine with Variables/Mixins
Nesting works best with other preprocessor features. For example:
/* Use variables with nesting */
$primary: #007bff;
.btn {
background: $primary;
&:hover {
background: darken($primary, 10%); /* Darken on hover (Sass function) */
}
}
✅ Test Compiled CSS
Always inspect the compiled CSS to ensure nesting isn’t creating unintended specificity or bloat. Tools like SassMeister let you preview compiled output.
7. Conclusion
Nested styles revolutionize CSS by aligning code with HTML structure, reducing repetition, and improving readability. While vanilla CSS now supports basic nesting, preprocessors like Sass and Less take it further with advanced features (variables, mixins, modules) that make styling at scale feasible.
By mastering nesting and following best practices, you’ll write CSS that’s cleaner, more maintainable, and easier to debug. Whether you choose Sass or Less, nesting will become an indispensable part of your workflow.
8. References
- Sass Documentation
- Less Documentation
- MDN: CSS Nesting
- Sass Guidelines: Nesting
- CSS-Tricks: Sass vs. Less
Happy nesting! 🚀