Remember nesting in HTML? The thing we do all the time when we put a <p>
in a <div>
and a <span>
in the <p>
like this?
<body>
<div>
<p>
<span></span>
</p>
<div>
</body>
I bet you do. SCSS allows us to nest CSS selectors in a similar manner. Nesting is a shortcut to creating CSS rules. So instead of writing so many lines of CSS just to be specific on the style we want to apply to an element, we simply nest it. Let's use an example. In CSS, we want to style the li
of a particular sidebar in a certain way, here's how we will target it.
#sidebar ul li {
background-color: #F2F2F2;
color: #404040;
}
Using nesting, we will simply do the following and get the same results.
#sidebar {
ul {
li {
background-color: #F2F2F2;
color: #404040;
}
}
}
This is better organized and it is easier to see the hierarchy. It produces the same result. You can add properties to the selector itself and not just to the nested selectors.
#sidebar {
position: fixed;
height: 100%;
ul {
list-style-type: none;
padding: 0;
li {
background-color: #F2F2F2;
color: #404040;
}
}
}
This will compile to
#sidebar {
position: fixed;
height: 100%; }
#sidebar ul {
list-style-type: none;
padding: 0; }
#sidebar ul li {
background-color: #F2F2F2;
color: #404040; }
You can also nest media queries too.
#sidebar {
position: fixed;
height: 100%;
@media (max-width:768px) {
left: -9999;
}
ul {
list-style-type: none;
padding: 0;
}
}
This will compile to
#sidebar {
position: fixed;
height: 100%; }
@media (max-width: 768px) {
#sidebar {
left: -9999; } }
#sidebar ul {
list-style-type: none;
padding: 0; }
We can even nest CSS properties.
li {
background: {
image: url("image.jpg");
position: fixed;
}
margin : {
top: 1rem;
left: 2rem;
right: 1rem;
}
}
This will compile to
li {
background-image: url("image.jpg");
background-position: fixed;
margin-top: 1rem;
margin-left: 2rem;
margin-right: 1rem; }
Really, nesting makes life a whole more easier. Let's next consider how we can use the ampersand &
to nest pseudo classes and elements and to place selectors side by side.
The Ampersand in Nesting
In Sass, &
is a very useful feature in nesting. If you want the selectors to be attached without leaving any space in between, we have to use the ampersand. This is especially useful when we have to nest pseudo-classes and pseudo-elements. If you want understand what pseudo-classes and pseudo-elements are, you can read this post. &
is also useful when we have to place classes side by side to select elements that have those classes. Let's use an example to understand this.
.list {
background-color: white;
color: #404040;
/* Pseudo-class */
&:hover {
background-color: blue;
color: white
}
/* Pseudo-element */
&:before {
content: "List ";
}
/* Placing selectors side by side */
&.active {
border-left: 3px solid blue;
color: blue;
}
}
This will compile to
.list {
background-color: white;
color: #404040; }
.list:hover {
background-color: blue;
color: white; }
.list:before {
content: "List ";
width: 30px; }
.list.active {
border-left: 3px solid blue;
color: blue; }
See how they are all joined side by side with no space between? That's the power of the &
.
CAUTION!!!
Nesting is very useful and makes our CSS organized but we do not want to misuse it. One way we can misuse it is by over-nesting selectors. Look at an example of over-nesting.
div {
.sidebar{
position: fixed;
height: 100%;
ul {
list-style-type: none;
padding: none;
.list {
background-color: white;
color: black;
a {
text-decoration: none;
i{
&:hover {
background: transparent;
}
}
}
}
}
}
}
This will compile to
div .sidebar {
position: fixed;
height: 100%; }
div .sidebar ul {
list-style-type: none;
padding: none; }
div .sidebar ul .list {
background-color: white;
color: black; }
div .sidebar ul .list a {
text-decoration: none; }
div .sidebar ul .list a i:hover {
background: transparent; }
Look at the last selector, that's six levels of nesting. That's so much. There's a lot of things wrong with this.
- Increase in file size: Look at the amount of code it added to the CSS file. This in turn increases the size of your file and affects performance.
- Specificity issues: Being too specific is itself a problem. A style in a selector that is very specific will be difficult to be overridden by another selector.
- Maintainability: This is also a problem. A change in any of the selectors in the top level selectors affects the other selectors.
- Styles are also not so reusable.
A rule of the thumb is not to nest more than 4 levels. Less than four levels is preferable. Rather than so many levels of nesting, you can use it to name your selectors and still be specific. See an example below.
.sidebar {
position: fixed;
height: 100%;
&-list {
background-color: white;
&-link {
text-decoration: none;
}
}
}
This will compile to
.sidebar {
position: fixed;
height: 100%; }
.sidebar-list {
background-color: white; }
.sidebar-list-link {
text-decoration: none; }
See how much better this is. We exploited the power of nesting and still kept our code maintainable and reusable. So the key is using nesting in a way that it doesn't affect performance and its maintainability.
And it's a wrap. Thank you for reading. :)
Got any question or addition? Leave a comment.
Top comments (11)
Great tutorial, I like that you've also made a caution about the excessive nesting.
In my work I avoid styling elements by
#id
's. Usually I use them only as anchors.Also a quick note about naming. For example you've used
.sidebar-list-link
.I prefer to avoid this kind of "nesting" in naming as well and use only one level of nesting. So I would do
.sidebar
and.sidebar-list
. And.list
maybe with.for-sidebar
modifier with.list-link
. Basically I would follow a bit modified version of BEM methodology.Thanks for the addition. 😊😊
Great article! Another use for the ampersand that people might find useful would be to reference parent selectors with the ampersand at the end.
Very powerful!
Awesome!!! Thanks for sharing this Lynne.
Great tutorial. A fantastic tip on this:
Never thought about doing that.
Thank you😊
Well explained.
Just an addition: I've been using stylelint and stylelint-config-sass-guidelines to keep my SASS files in check and you can also configure it to set a maximum nesting depth.
That's awesome. I'll look at them. Thanks for sharing.
what does the
&
do when it is before or after a nestedclass
orid
??Nesting with SASS does not seem to work for me? banishing negativity spells
Should you nest everything in SASS? comment rendre un homme amoureux