If you’ve spent any time developing CSS you’ve probably written plenty of lines like the following:
nav.tabbed-navigation { … }
nav.tabbed-navigation a { … }
nav.tabbed-navigation a span { … }
While this works, it creates lot of repeated lines in your stylesheet that are difficult to read, with a strong dependence on CSS descendant selectors: if the class
name on the <nav>
element changes, you’ll have to rewrite all three CSS selectors in the example. With a preprocessor like Sass, you can take a different approach.
First, let’s move to CodePen and create a navigation bar very quickly, using the Emmet shortcuts I mentioned in the previous article. In the HTML tab, type:
nav.tabbed-navigation>(a[href="#"]*5>span{Click}+{ me})
Then immediately press TAB on your keyboard to expand the shortcut. (You can adjust the text inside each link later, if you wish)
Set the CSS in CodePen to accept .scss, as shown in the previous article, then type the following inside the associated pane:
.tabbed-navigation {
background: #ccc;
padding: 1rem;
a {
text-decoration: none;
color: #333;
}
}
The CSS this generates – currently invisible to us, but active in the CodePen preview pane – is:
.tabbed-navigation {
background: #ccc;
padding: 1rem;
}
.tabbed-navigation a {
text-decoration: none;
color: #333;
}
Let’s take this one step further. Modify the CSS you’ve written so far to:
.tabbed-navigation {
background: #ccc;
padding: 1rem;
a {
text-decoration: none;
color: #333;
span {
font-weight: bolder;
}
}
}
The resulting CSS (and its effect on the <nav>
element) is the same as if you’d written each declaration seperately, but the Sass is much easier to write… and if the class name on the root element changes, there’s just one selector to rewrite, rather than three different copies.
Making Hovers Easy
Extending the idea of nesting further, we can use the ampersand symbol (&) to reference parent selectors. Change the Sass code to the following:
$linkcolor: #333;
$linkhighlight: #fff;
body {
font-family: Avenir, Helvetica, sans-serif;
}
.tabbed-navigation {
background: #ccc;
font-size: 0;
a {
text-decoration: none;
font-size: 1rem;
display: inline-block;
padding: 1rem;
transition: .3s background;
color: $linkcolor;
span {
font-weight: bolder;
}
&:hover {
background: $linkcolor;
color: $linkhighlight;
}
}
}
You can see the result in the associated CodePen. By creating variables for the link text and background (discussed in the previous article) and adding a hover state underneath the links, we can easily control the appearence of the final UI while guaranteeing design consistency across our site.
Don’t Delve Too Greedily, Or Too Deep
Obviously, this kind of Sass selection can be taken a lot deeper, essentially replicating the DOM in CSS. However at a certain point – broadly agreed by to be anything more than four levels deep – Sass nested selectors become too complex, too difficult to read, and too closely tied to the markup. Nesting makes sense in many situations, and can save significant amounts of coding time, but be careful not to use it in excess.
Use CSS Inheritance Wisely
You can use CSS values like inherit
and currentColor
to enhance nesting further, making maintenance easier. For example, if you want the navigation bar links to be the same color as body text, you could write:
body {
color: #333;
}
nav.tabbed-navigation {
background: #ccc;
padding: 1rem;
a {
text-decoration: none;
color: currentColor;
span {
font-weight: bolder;
}
}
}
Naturally, these color choices could also be expressed as Sass variables.
Next, I’ll look at one of the most useful features in Sass, one that makes modern modular, object-oriented CSS development easier and much more powerful: @extend
Photograph by furtwangl, used under a Creative Commons Attribution 2.0 Generic license
Enjoy this piece? I invite you to follow me at twitter.com/dudleystorey to learn more.
Check out the CodePen demo for this article at https://codepen.io/dudleystorey/pen/vEmwaB