Nesting in Sass
You’re already familiar with the concept of nesting from writing HTML. When you write a list in HTML, the li
element is nested inside of another HTML element (either ul
or ol
):
<ul> <!-- parent element -->
<li>List item</li> <!-- nested child element -->
</ul>
With Sass, you can do something similar with selectors and certain CSS properties.
Nesting selectors
Nesting selectors in Sass has the same logic as the HTML above. The following is valid Sass:
ul {
li {
background-color: silver;
}
}
When compiled to CSS, the resulting code will look like this:
ul li {
background-color: silver;
}
This is helpful, as it lets you write less code, but it definitely can be taken to an extreme. It is not necessary or helpful for your Sass to mirror your exact HTML structure.
For example, if you had the following HTML:
<header class="container site-header">
<a href="#" class="site-name">Site name</a>
</header>
<nav class="container site-nav">
<ul>
<li><a href="#">About</a></li>
<li><a href="#">Blog</a></li>
<li><a href="#">Contact</a></li>
</ul>
</nav>
And you wanted to modify the text-decoration
property on the a
element inside that list, you should not do this:
❌ Don’t do this
nav.site-nav {
ul {
li {
a {
text-decoration: none;
}
}
}
}
Writing your Sass like that would result in the following CSS:
nav.site-nav ul li a {
text-decoration: none;
}
This is an overly specific selector, which was warned against in the reading you did on the cascade in CSS.
Since the Sass you write results in CSS, the same rules and best practices should still be kept in mind.
Instead, write your Sass like so:
.site-nav {
a {
text-decoration: none;
}
}
Which will result in this much more reasonable selector in your CSS: .site-nav a
In the movie Inception, there’s a stated rule about how deep into layered dreams is safe to go…and you should have similar guidelines for your Sass.
When nesting, stick to 2 layers, 3 at the max. Otherwise, things get unweildy.
OK, maybe a slight exaggeration, but the ruleFollowing and reading this link is optional.✳️ still stands. 😹
Nesting properties
In addition to selectors, you can also nest certain CSS properties. If properties share a prefix, they can be nested. For example, font-size
and font-weight
share the same prefix and can be nested like so:
p {
font: {
size: 24px;
weight: bold;
}
}
This would compile to the following CSS:
p {
font-size: 24px;
font-weight: bold;
}
You can do the same thing with properties that begin with:
margin-
padding-
text-
- and many others.
Like nesting selectors, this can save you time typing and keep your properties tightly organized.
Parent selector
In Sass, the ampersand (&
) is called the parent selector and can be used when nesting your code to reference the outer selector.
A demonstration using the parent selector with pseudoclasses will help make this clearer; if you write the following Sass:
a {
color: orange;
&:hover, &:focus {
color: red;
}
}
It will result in the following CSS:
a {
color: orange;
}
a:hover, a:focus {
color: red;
}
Here, you can see that the ampersand gets replaced by the a
element, completing the hover and focus effect styles on the link.
Like other nesting rules, the parent selector is powerful, but can get convoluted. Using it for hover and focus effects is recommended because it allows you to nest those effects within the parent selector, but you don’t have to invent additional clever ways of using this, especially as you’re starting out with Sass.
Nesting demonstration
This stylesheet refactors the code from the lessons on organizing your CSS and Sass variables. Taking just the header and navigation elements styles, I’ve updated them to use Sass nesting. I’ve commented out the original CSS so you can still see what and how I modified the code. Look for changes specifically starting on line 58:
This refactor includes examples of each type of nesting:
- nested selectors (line 141)
- nested properties (line 178)
- nested parent selector (line 157)