Just as you nest Ā <li>s within an Ā <ul>Ā in HTML, you can nest their selectors within Sass:
ul {
list-style: none;
text-align: right;
li {
display: inline;
font-size: 3rem;
color: #D6FFF5;
}
}Now that you have a clear hierarchy of the selectors reflecting their HTML structure, your Ā <li>sĀ are nested within theĀ <ul>, just like they would be in HTML.
Rather than having to scroll through a CSS file looking for individual selectors and their rule sets, you can go to a single spot in the file and see how Ā <ul>s and their childĀ <li>Ā are styled. That means you only have to go to one location to make updates in the future.
Cleaner? Check. ā Maintainable? Check. ā
Take a look at the resulting CSS:
ul {
list-style: none;
text-align: right;
}
ul li {
display: inline;
font-size: 3rem;
color: #D6FFF5;
}
The Ā <ul>Ā received all of the rules assigned outside of the nested selector. And the Ā <li>Ā received the rules that were assigned within its nested selector. Notice that the Ā <li>Ā isnāt a singular element selector. Instead, weāve created a descendant combinator.
Letās give our CSS some structure and put our new-found nesting knowledge to use.Ā In this interactive exercise, we have a Ā .parentĀ selector, and a Ā .childĀ selector. Letās organize them to reflect their relationship using Sassā nesting by placing the Ā .childĀ rule set within the Ā .parentĀ rule set.
Nest theĀ .childĀ selector and its contents withinĀ .parent
Once you've tried it yourself, check your work in this CodePen!
Weāve performed the most basic form of nesting within Sass, which is placing a selector within another selector. Sass will always compile this as selectors separated by spaces, which, in CSS, is a descendant combinator.
If you can create descendant combinators, it stands to reason that you can create other combinators as well! In fact, you can create any of the otherĀ CSS combinators:
.parent {
background-color: #15DEA5;
}
.parent .descendant {
color: #fff;
}
.parent > .child {
color: #D6FFF5;
}
.parent + .adjacent {
color: #001534;
}You remember these, right? Let's do a little recap:
In the first case, anythingĀ relatedĀ to the parent element will take on the designated background color.Ā
In the second case, if the second element is theĀ descendantĀ of the first element, then it will have the specified color.Ā
In the third case, if the second element is aĀ childĀ of the first element, it'll have the designated color.Ā
In the fourth case, if the second element is immediatelyĀ precededĀ by the first, it'll have the supplied color.Ā
Wait, what's the difference between "descendant" and "child"?Ā
It's actually the same as in plain English:
You are both theĀ childĀ and theĀ descendantĀ of your parents.Ā
You aren't the child of your grandparents, but you are theirĀ descendant.Ā
A child element, therefore, has a direct and immediate link to the parent element.
By adding the appropriate combinator symbol before a nested selector, you can create any of theĀ CSS combinators in Sass:
.parent {
background-color: #15DEA5;
.descendant {
color: #fff;
}
>.child {
color: #D6FFF5;
}
+.adjacent {
color: #001534;
}
}When you nest a block in Sass, it creates an individual CSS selector with the parent selector appended, separated by the appropriate combinator.
Itās time to get all familial and whatnot as we create selectors that style based on their relationship to the root selector. The code base already contains a selector for the ārootā class. Letās use nesting and combinators to style the elements surrounding and within the Ā .rootĀ element in the HTML file.
Nest a selector for the Ā .generalĀ class using the general sibling combinator ( Ā ~Ā ) and assign it a background colorĀ of your choosing
Nest a selector for the Ā .adjacentĀ class using the adjacent sibling combinator ( Ā +Ā ) and assign it a background color of your choosing
Nest a selector for the Ā .childĀ class using the child combinator ( Ā >Ā ) and assign it a background color of your choosing.
Nest a selector for the Ā .descendantĀ class using the descendant.
Normally the descendant combinator is a space āā, but with Sass, directly nesting a selector will compile as the space of the descendant combinator in the CSS.
Assign the nested Ā .descendantĀ selector a background color of your choosing.
Review the resulting rendered HTML in the browser pane andĀ compare your answer to mine with this CodePen.
But what if we donāt want a separation between the parent and child?
To do that, you'll harness the power of the ampersand!
You need to add a Ā li:hoverĀ pseudo-class to your Ā <li>s to provide visual feedback and better the user experience. So, letās nest the pseudo-selector within ourĀ liĀ selector:
ul {
list-style: none;
text-align: right;
li {
display: inline;
font-size: 3rem;
color: #D6FFF5;
:hover {
color: #001534;
}
}
}Which compiles to:
ul {
list-style: none;
text-align: right;
}
ul li {
display: inline;
font-size: 3rem;
color: #D6FFF5;
}
ul li :hover {
color: #001534;
}Well, that won't work⦠š Remember that nesting in Sass creates combinators. But you donāt want a combinator before your pseudo-selector. Thatās not how they work; you need it to beĀ immediately joined to their selectorĀ to have the desired effect.
Sass has a special character to concatenate the parent and child selectors: theĀ ampersand (&)!Ā Prefixing a nested selector with an ampersand will directly join it to the parent selector without any combinators.
So, letās add an ampersand before our Ā :hoverĀ pseudo-selector:
ul {
list-style: none;
text-align: right;
li {
display: inline;
font-size: 3rem;
color: #D6FFF5;
&:hover {
color: #001534;
}
}
}And check out the resulting CSS:
ul {
list-style: none;
text-align: right;
}
ul li {
display: inline;
font-size: 3rem;
color: #D6FFF5;
}
ul li:hover {
color: #001534;
}Much better! Now we have a properly functioning hover state for our Ā <li>Ā s, all built within a single block of code.
Nesting in Sass is awesome, but sometimes we might want to nest a selector that doesnāt work any of the CSS combinators, such as pseudo-selectors likeĀ :hoverĀ andĀ :focus. For times like those, we want to use the ampersand ( & ) to join the name of the parent to child being nested. In this interactive exercise:
Nest aĀ :focusĀ selector within theĀ .inputĀ class selector
Add a new background color and font color to the theĀ :focusĀ selector
Check out the result by interacting with the text box in the browser pane
Think you've got it? Compare your solution to mine in this CodePen!
Thereās no physical limit as to how deeply you can nest within Sass. It can be tempting to completely mirror your HTML within your Sass, creating a perfect replication of the hierarchy.
.parent-div {
background-color: #15DEA5;
.child-div {
color: #fff;
.grandchild-div {
color: #D6FFF5;
}
}
}But, remember, when you nest selectors, you increase the specificity of the compiled selectors. So, if you nest too deeply, youāll end up with selectors of incredibly high specificity, making them extremely difficult to modify or override.
.parent-div {
background-color: #15DEA5;
}
.parent-div .child-div {
color: #fff;
}
.parent-div .child-div .grandchild-div {
color: #D6FFF5;
}Trying to override a selector as specific as Ā .parent-div .child-div .grandchild-divĀ would require an even more specific selector. It also greatly hinders the re-usability of your code; unless you were to add an element later that exactly matches this hierarchy of classes, this selector is completely useless. This is brittle code that will be difficult to maintain. And that defeats the purpose of using a preprocessor at all!
Rather than trying to replicate the hierarchy of the HTML, it is better to write nested selectorsĀ only relative to the root selector.Ā It wonāt represent the HTML structure as clearly, but it helps to ensure a low specificity in your codebase while maintaining flexibility and modularity.
Time to roll up your sleeves for another interactive exercise!
In this CodePen, move the nestedĀ .particleĀ selector up one level in the hierarchy, putting it on the same level as theĀ .atomĀ selector.
The rendered HTML should now look a bit different, with anotherĀ .particleĀ div showing up that wasnāt styled by the previously over-specificĀ .particleĀ selector.
Check your end result with this CodePen.
Nesting in Sass is an extremely powerful tool that helps you to group relevant selectors, creating a codebase that is easy to navigate and maintain. However, it does have the drawback of ballooning specificity. Now, you might be thinking back to BEM, and the organization and structure it helps impart on your selectors. You might alsoĀ recall that itās built upon a foundation of low specificity. Which is at direct odds with the increase in specificity that comes from nesting. So, which should you use? BEM or nesting?
I would ask: why not have your cake and eat it too? š° That's what we'll show you how to do in the next chapter. Weāll combine the power of Sass and the order of BEM to create flat selectors, while maintaining the structure of nesting.
In Sass, selectors can be nested inside other selectors.
Sass can create any of the CSS combinators.
Use the ampersand to join a nested selector to a parent selector without using a combinator.Ā
Be wary of creating overly specific selectors.Ā