Organizing Nested Selectors in Sass

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
 &: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 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 posts by Jeremy