HTML & CSS
Article

Sass Basics: Nesting

By Reggie Dawson

When you are just starting out using Sass one of the first features you will hear about is nesting. One reason we may use a preprocessor is to lessen the amount of typing we need to create CSS rules. Nesting allows us to use shortcuts to create our rules. The problem with all great tools is that the potential for misuse is always there. Nesting is no different as overuse can create complex, unmanageable stylesheets.

What is Nesting

Nesting allows you to write selectors that mimic the structure of your HTML. This allows you to use shortcuts to create your CSS. For example:

div {
    p {
        color: black;
    }
}

This is nesting at its simplest. The div element encloses the P element. This will in turn compile to.

div p { color: black; }

We could have also given the div its own properties.

div {
    font-size: 14px;
    p {
        color: black;
    }
}

This in turn compiles to two separate rules, one for the div by itself and another for the p element inside of the div.

div { font-size: 14px;}
div p { color: black; }

How to use nesting

Nesting styles is simple enough. You just enclose a selector (or selectors) inside the curly braces of another selector.

.parent {
    .child {
    }
}

Nesting can extend as many levels deep as you wish. What this means is that you can nest elements inside of an element that is in turn nested inside another element.

.first-level {
    .second-level {
        .third-level {
            .fourth-level {
            }
        }
    }
}

There is really no limit to the amount of levels deep that you can nest elements. The main thing to remember is just because you can do something does not mean you should. It is generally a good idea to not nest deeper than three levels. Anything more than that starts to affect the readability of the code. Sass is there to help us write CSS faster, not to create a bunch of styles that are not maintainable. For example

.page {
    font-family: sans-serif;
    .content {
        background-color: black;
        .text {
            color: white;
            font-size: 12px;
            .headline {
                font-weight: bold;
                a {
                    color: blue;
                    &:visited {
                        color: green;
                    }
                    &:hover {
                        color: red;
                    }
                    &:active {
                        color: yellow;
                    }
                }
            }
        }
    }

}

Looks innocent enough with nesting that extends five levels deep. A look at the compiled output illustrates the problems with nesting too deep.

.page { font-family: sans-serif; }

.page .content { background-color: black; }

.page .content .text { color: white; font-size: 12px; }

.page .content .text .headline { font-weight: bold; }

.page .content .text .headline a { color: blue; }

.page .content .text .headline a:visited { color: green; }

.page .content .text .headline a:hover { color: red; }

.page .content .text .headline a:active { color: yellow; }

This presents a problem if we change the structure one of our webpages. Lets say we changed .content to .article. All underlying classes will have to be re-written as they are all dependent on being inside .content.

We also have problems with the rules we are creating being useful in only one part of our code. If we wanted to use the styles for .text somewhere else on our site we cannot since .text is bound to the elements that enclose it.

Referencing parent selectors

In the terrible example above we use an ampersand, &, to specify where the parent selector needs to be placed. The : is used in the above example to create a pseudo-class of the anchor element.

a {
    color: blue;
    &:visited {
    color: green;
    }
    &:hover {
    color: red;
    }
    &:active {
    color: yellow;
    }
}

This compiles to

a { color: blue; }

a:visited { color: green; }

a:hover { color: red; }

a:active { color: yellow; }

By itself this is very readable and as a result maintainable by anyone. You can also use the & to build compound selectors. You do this by following the ampersand with a suffix. For example:

.col {
    &-span1 { width: 8.33%; }
    &-span2 { width: 16.66%; }
    &-span3 { width: 24.99%; }
}

Which give us

.col-span1 { width: 8.33%; }
.col-span2 { width: 16.66%; }
.col-span3 { width: 24.99%; }

As you can see the parent selector is placed where the ampersand is.

Nested properties

Sass also provides a shorthand for writing styles using CSS namespaces. Normally when setting properties in the same namespace, for example border, we have to write out individual properties in our style sheet. With Sass we can write the namespace once and nest its properties.

.example {
    border: {
        style: dashed;
        width: 30px;
        color: blue;
    }
}

This compiles to

.example {
    border-style: dashed;
    border-width: 30px;
    border-color: blue;
}

As you can see the namespace is appended to the properties. Unlike the above example we did not have to include the & for border to show up in the correct place.

Conclusion

Now that you know what nesting is please use it responsibly. Sometime when building a project we can lose sight of the scope of what we are building. Its easy to create a nightmare of readability when nesting with Sass. When and how to use nesting is up to you, if you decide to go 8 levels deep by all means go for it. Just be prepared for long nights of work if a project has major overhaul.

Comments
verpixelt

Thanks for this intro into the problems the misusage of nesting can lead to. I've also written an article about this topic you might be interested in: https://medium.com/@verpixelt/your-nesting-is-harmful-a1ffddaf7e43

Recommended

Learn Coding Online
Learn Web Development

Start learning web development and design for free with SitePoint Premium!

Get the latest in Front-end, once a week, for free.