SASS Video Tutorial: Why I don’t nest in SCSS

In this video I invite you to discover why I don’t like nesting in SCSS and how it can be bad for the organization of your style sheets.

What is nesting

With the SASS preprocessor and PostCSS it is possible to put the rules into each other to better organize themselves.

.header {
    .logo {
        color: #000;
    }
}

This generates the following CSS

.header .logo {
    color: #000;
}

In the same way, it is also possible to reuse the previous rules using the symbols &.

.header {
    &__logo {
        color: #000;
    }

    .dark & {
        background: #000;
    }
}

Which will generate the following CSS

.header__logo {
    color: #000;
}
.dark .header {
    color: #000;
}

Rather practical when using the BEM technique for example.

But it’s too good!

At first glance, this nesting may seem like a good idea to organize your rules according to a particular context. However, in reality, this turns out to be a double-edged sword. So, to put things into perspective, here are the reasons why I personally avoid nesting in my projects.

Reason 1: Too specific rules

The first example cited above has the main drawback of creating rules with a high trpp specificity because of the accumulation of selectors.

.header .navbar .logo {
    color: #000;
}

This specificity makes the cascade more difficult when it comes to changing certain properties. For example, if you want to apply a dark mode, you will need a rule that is at least as precise.

.dark .header .navbar .logo {
    color: #FFF;
}

In this situation, we prefer to use a simpler selector.

.header-logo {
    color: #FFF;
}

By keeping first-level selectors, it is easier to control the global specificity of your rules in order to be able to overwrite them more easily later in case of cascading.

Reason 2: Difficult readability if too much depth

If used too much, nesting can create too much depth that makes readability more difficult than necessary (much like nesting too many conditions in a programming language).

  // ...
  &__menu {
    .icons {
      width: 100%;
      max-width: calc(var(--col-width) + 15rem);
      margin: 0 auto;

      &__item {
        position: absolute;
        z-index: -1;
        user-select: none;

        &--youtube {
          left: 30%;
          top: 82.92px;
        }

        &--facebook {
          left: 88.15%;
          right: 8.43%;
          top: 22%;
          transform: rotate(25deg);
        }
      }
    }
  }
}

It then becomes difficult to scan the CSS code visually and to predict the rules that will be generated as output.

Reason 3: Rules are hard to find

The rules generated by nesting are also more difficult to find. Even if some editors are able to automatically find the definition in the SCSS from the classes of your HTML code, this is not the case for all editors. You will then have to rely on the classic search function but which will not work if the rule is broken down.

// On ne trouvera pas cette règle en cherchant ".header__menu"
.header {
    &__menu {
        display: flex;
    }    
}

Reason 4: Reviews are harder

This nesting also poses problems during code review because the versioning tools git diff shows some line around modified lines. Also, because of the nesting it is often necessary to go back several decades to find the selector associated with the modification.

Adapted the rule to the problem

Despite all these reasons, however, there are situations where nesting can be used without the problems listed above.

For example for pseudo elements or to define the states associated with a property.

.button {

  background: blue;
  color: #FFF;
  padding: .2rem 1rem;
  border: none;

  &:hover {
    background: #FFF;
    color: #000;
  }

  &::before {
    content:'';
    background: url(img/icon.png);
    width: 100px;
    height: 100px;
  }

  &.is-active {
    box-shadow: 0 0 4px 0 lightblue;
  }

}

In this case I try never to exceed a level of depth while knowing that my research will be based on “.button”. But if the properties are too numerous then I revert to a classic CSS syntax.

Also, nesting can be used in the case of media queries in the case of a simple modification.

.button {

  background: blue;
  color: #FFF;
  padding: .2rem 1rem;
  border: none;
  font-size: 1rem;

  @media only screen and (min-width: 1000px) {
    padding: .5rem 2rem;
    font-size: 1.2rem;
  }

}

However, care must be taken not to multiply the number of media queries that will be generated as output. In this case, we prefer the more classic approach with the media queries at the end of the file.