SASS: Nesting can be dangerous.

I remember the first time I picked up a CSS preprocessor (LESS). I loved the way that I could write the classes that I needed in a more expressive way.

I also remember the first time I encountered a stylesheet with a class that looked like:

.super-awesome-container .super-awesome-list .list-item .containing-anchor > span:first-of-type > .icon > img.awesome-icon

Of course, this wasn't the first overly specific in the file. It was plagued with many more like it. Many more just a couple of layers shallower. And some more that were deeper.

Obviously this looks ridiculous, probably has some slight performance issues and mostly causes maintainability issues due to unnecessarily complex specificity.

So how did this come up?

.super-awesome-container {
  display: block;

  .super-awesome-list {
    width: 80%

    .list-item {
      display: inline-block;
      padding: 0.5rem;

      .containing-anchor {
        text-decoration: none;

        &> span {
          color: $light-gray;

          &:first-of-type {
            color: $brand-green;

            &> .icon {
              padding-right: 1rem;

              img.awesome-icon {
                width: 0.75rem;
                height: 0.75rem;
              }
            }
          }
        }
      }
    }
  }
}

Nesting.

When I worked at The Nerdery I was exposed to some interesting front-end practices that seemed a little unnecessarily burdensome. And then it clicked.

Our engineers were practicing writing much flatter SCSS and it was allowing for descriptive naming in our markup, decoupling our markup from our display, and it was allowing us to inherit styles as necessary but cut down on using !important and other dangerous practices because we couldn't sort out our specificity.

Consider if we had a more flat structure with that SCSS before...

.super-awesome-container {
  display: block;
}

.super-awesome-list {
  width: 80%;
}

.super-awesome-list-item {
  display: inline-block;
  padding: 0.5rem;
}

.super-awesome-list-item-link {
  text-decoration: none;

  &> span {
    color: $light-grey;

    &:first-of-type {
      color: $brand-green;
    }
  }
}

.super-awesome-list-item-icon {
  padding-right: 1rem;

  img {
    width: 0.75rem;
    height: 0.75rem;
  }
}

This could be improved too. But the improvements so far are meaningful. Sure, class names become longer, but they're more descriptive, especially in the markup.

Moreover, we've eliminated some over-specificity that comes from writing markup and SCSS at the same nesting levels and writing SCSS that mirrors the format of your markup. So we're still specific about some things, that could be flatter like .super-awesome-list-item-icon img but we're moving in the right direction.

In small apps or marketing sites, this may not be an issue for you. But in an increasingly mobile-dominant web, we should be considerate about our users' data plans, connection speeds and our own bandwidth. The extreme example demonstrated above, occurring hundreds of times through a codebase can have a balloon effect on your compiled CSS file when it doesn't need to.