How To Nest Selectors And Properties In Sass

Do you want to write CSS that’s well organized, easier to read, and easier to maintain? Nesting is a feature of Sass that can help you keep related selectors and properties together to make your code more readable and maintainable.

Bird's Nest with Eggs

The last couple of weeks I offered an introduction to Sass. I talked about CSS preprocessors in general and walked you through some of the set up for installing Sass. I also showed you some code so you could see how to work with Sass. A few times I mentioned that we’d get to the more exciting features of the language in the coming weeks.

One of the first features of Sass you’ll likely use is nesting. It’s a natural first step into what Sass can do and while it may look a little odd at first, it won’t take long to get used to.

However, not everyone agrees that you should nest your code. You can get carried away with nesting and cause more harm than good if you don’t follow a few basic guidelines. Like most everything, there are pros and cons to nesting and I’ll talk more about both next week.

Before we can understand the good and bad of nesting though, we should first talk about how it works.

Nesting Selectors

The easiest way to begin is with an example. With CSS it’s common to chain selectors together as in the following example.

1
2
3
4
5
6
7
8
footer {  
  background: #444;  
}

footer p {  
  font-size: 0.875em;  
  line-height: 1.2;  
}

This code sets a background color on the footer and then sets font-size and line-height for paragraphs specifically inside the footer. The footer p selector combines or chains two selectors together so the code inside the selector only applies to paragraphs inside footer elements.

Here’s how you could do the same through nesting in Sass.

1
2
3
4
5
6
7
footer {  
  background: #444;

  p {  
    font-size: 0.875em;  
    line-height: 1.2;  
}

Instead of writing the selector footer p, notice that the paragraph selector is written inside the brackets for the footer selector.

The nested code will compile to:

1
2
3
4
5
6
7
footer {  
  background: #444;  
}
footer p {  
  font-size: 0.875em;  
  line-height: 1.2;  
}

Note: I’m using the :expanded output style, since it’s the easiest to read. Your CSS output may look different if you’re using a different output style.

The compiled code is the same as the CSS in the original example. Even with a different output style, the code is still functionally the same. The only difference is the whitespace that is or isn’t used.

You aren’t limited to two levels of nesting.

1
2
3
4
5
6
7
footer {  
  p {  
    a {  
      color: #fff;  
    }
  }  
}

With this code you can see you’re dealing with links inside paragraphs inside the footer. The Sass compiles to:

1
footer p a {color: #fff;}

You may think the single line looks cleaner, but keep in mind this is a very simple example. I think nested Sass is easier to read as you add more code, though again not everyone agrees.

While you can technically nest selectors as many levels deeps as you want, you do have to be careful not to nest too deeply. If you do, you’ll run into the same problems associated with chaining too many selectors together.

I try to limit nesting to two levels, though I will go three levels deep at times. Given the same HTML structure of a link inside a paragraph inside a footer, I would probably nest my Sass as follows.

1
2
3
4
5
6
7
8
9
10
11
12
13
footer {  
  p {  
    styles here;  
  }

  a {  
    styles here;

    &:hover {  
      styles here;  
    }
  }  
}

Instead of nesting the link inside the paragraph I only nested the link inside the footer. The selector, footer a is less specific than footer p a. I reserved the the third level for the :hover pseudo selector.

Referencing Parent Selectors (&)

One of the things I often find myself doing with links is to remove the underline and then add it back on :hover.

1
2
3
4
5
6
7
a {  
  text-decoration: none;  
}

a:hover {  
  text-decoration: underline;  
}

Sass uses the ampersand as a short cut to reference the parent selector.

1
2
3
4
5
6
7
a {  
  text-decoration: none;

  &:hover {  
    text-decoration: underline;  
  }
}

The ampersand will be replaced with the parent selector and the compiled code will look like the initial block of CSS.

It’s not exactly a time saver in this particular example as & and a are both single characters, but the reference works with parent selectors that are longer than a single character.

You can also use the ampersand for more than pseudo elements like :hover. Here the ampersand is followed by the suffix -green

1
2
3
4
5
6
7
8
.btn {  
  padding: 1em;  
  font-size: 1.2em;

  &-green {  
    background: green;  
  }
}

which compiles to:

1
2
3
4
5
6
7
.btn {  
  padding: 1em;  
  font-size: 1.2em;  
}
.btn-green {  
  background: green;  
}

If you use BEM or SMACSS when writing your CSS, you can probably see how referencing parent selectors like this can be useful.

If the parent selector can’t have a suffix applied and still be valid CSS, Sass will throw an error. For example:

1
2
3
4
5
6
7
:nth-child(5) {  
 color: #fff;

 &-suffix {  
   color: #000;  
}
}

Here the ampersand reference would lead to:

1
:nth-child(5)-suffix

This isn’t a valid selector so Sass will throw an error when compiling.

Trailing Parent Reference

The ampersand can also be used as a trailing parent reference. For example say you have the following HTML.

1
2
3
4
5
6
7
<div class="one">  
  <p>Some text</p>  
</div>

<div class="two">  
  <p>Some text</p>  
</div>

Here we have two divs, each with a different class name. Both divs contain a paragraph with some text inside. Imagine that you want the text inside paragraphs to be black most of the time, but in the .two div you want it to be red.

You could reference the parent selector at the end of the selector as follows:

1
2
3
4
5
6
7
p {  
  color: #000;

  .two & {  
    color: #f00;  
  }
}

The Sass compiles to:

1
2
3
4
5
6
p {  
 color: #000;  
}
.two p {  
 color: #f00;  
}

Your typical paragraphs would use black text, while the paragraphs inside .two will use red text.

Nesting Properties

In addition to nesting selectors, Sass lets you nest properties within the same name space. For example font-family, font-size, font-style, font-weight, font-variant are all in the same font namespace.

Instead of writing each property in full like this you can take advantage of property nesting in Sass.

1
2
3
4
5
6
7
.headline {  
  font: {  
    family: georgia;  
    size: 2.4em;  
    weight: bold;  
  }
}

This compiles to:

1
2
3
4
5
.headline {  
  font-family: georgia;  
  font-size: 2.4em;  
  font-weight: bold;  
}

If you can write a property in shorthand, you can nest the properties in Sass.

1
2
3
4
5
6
7
8
p {  
 padding: {  
   top: 1em;  
   right: 2em;  
   bottom: 3em;  
   left: 4em;  
 }
}

which compiles to:

1
2
3
4
5
6
p {  
  padding-top: 1em;  
  padding-right: 2em;  
  padding-bottom: 3em;  
  padding-left: 4em;  
}

You can also include one or more values on the property namespace. For example:

1
2
3
4
5
6
.headline {  
  font: 2.4em/1.5 georgia {  
    style: italic;  
    weight: bold;  
  }
}

which compiles to:

1
2
3
4
5
.headline {  
  font: 2.4em/1.5 georgia;  
    font-style: italic;  
    weight: bold;  
}

I tend to use the shorthand as in padding: 1em 2em 3em 4em, but I think nesting properties like this is more readable.

Closing Thoughts

Nesting is one of the first features most people try when they started using Sass. I know it was the first feature of Sass I started using.

It took a little while for me to get used to nesting my code. Initially I wrote my code as though I wasn’t using Sass and I had to remind myself I could nest it. Now I’ll occasionally be working directly in a CSS file and have to remind myself that I can’t nest code in the .css file.

You do want to be careful that you don’t nest your code too many levels deep, but if you keep it to two or three levels you should be fine.

Nesting can fool you into thinking all your selectors are made up of single elements or classes when you’ve really chained a few together. This is one reason why you want to be careful not to nest too many levels deep, but let’s leave that discussion for next week when we talk about the pros and cons of nesting.

Download a free sample from my book, Design Fundamentals.

4 comments

  1. Hi Steven, this was really useful information. I was particularly looking on how to nest selectors in CSS and other technical features; your article has given some valuable insights into these aspects. Please continue to post such information.

Leave a Reply

Your email address will not be published. Required fields are marked *