Organizing Nested Selectors in Sass

Jeremy Fields, Platform Development Director

Article Category: #Code

Posted on

I love trying to figure out the best organizational systems for my code. At Viget, FEDs and Devs do regular code reviews and I usually take that opportunity to glean tips from colleagues on how to improve what I'm doing. Organizing CSS has been debated plenty, but what about preprocessed CSS? If you're using Sass/Scss or Less there's the additional challenge of organizing nested selectors. I've been thinking about this lately and here's where I've landed.

The Reasoning

This system is conceptually based around how closely related a nested selector is to the parent and its state.

Here's the commented code, check it out and share what you think in the comments.

.my-selector {

  /* mixins and extends first, unless they're specifically related to a rule */
  @include some-mixin;

  /*
   * styles and modifications directly on the parent selector
   */

  /* rules come first and are alphabetical, including rule-specific mixins */
  background-color: #fff;
  color: #000;
  @include font-size(16px);

  /* pseudo-classes follow because they narrow down a selection of the parent */
  &:first-child {

  }

  /* cascading modifier classes are next in case they need to be overridden later */
  .js & {

  }

  /* modifier classes directly on the element, like pseudo-classes also style states of the parent */
  &.-modifier {

  }

  /* action-based pseudo-classes are next because they style states of the parent */
  &:focus,
  &:hover {

  }

  /* media queries come next because they describe modifications to the parent */
  @media screen and ('max-width: 50rem') {

  }

  /*
   * nested elements and pseudo-elements
   */

  /* pseudo-elements are the first of the nested elements */
  &::after {
    content: 'hey, I am a pseudo element';
  }

  /* element selectors are next and are alphabetical */
  a {

  }

  p {

  }

  /* class name selectors are last because they can modify un-classed elements */
  .some-nested-selector {

  }
}

Hold On...

Don't get too nest-happy — too much nesting creates code bloat and specificity problems. Check out the inception rule or other techniques for managing preprocessed code complexity.

Jeremy Fields

Jeremy leads Viget's front-end development team, and has helped make accessibility part of every site we build. Based in our Boulder, CO, office, Jeremy has worked with clients like Time Life, PUMA, and Dick's Sporting Goods.

More articles by Jeremy

Related Articles