Mauro Bringolf

Currently geeking out as WordPress developer at WebKinder and student of computer science at ETH.

Alternative ways of nesting SASS style rules

Today I had to get an old WordPress theme ready for some changes to be made. If I remember correctly, all code in the project was written by myself but my tools and methods have evolved quite a bit since then. All styles were still written in raw CSS, something I don’t do anymore. We usually work with SASS to improve things. So I set up Gulp and wanted to make some changes to the navigation. Simple enough: take all relevant CSS rules, put them in a SASS file and start hacking. Working with just a handful of rules and having the old CSS equivalent as reference was a perfect setting to think about the advantages of SASS. It gives a lot of flexibility and cool features, but what does one really gain over CSS? Or put another way: What goals should I have in mind when structuring my SASS rules? Usually there are many ways of expressing a selector in SASS. Most of SASS features help reduce duplicate selectors, but today I realized that for me there is a bigger upside: adhering to the single source of truth principle.

Here is a reduced form of the example I encountered:

<ul>
  <li>
    <a href="/what">ever</a>
    <a href="/some">link</a>
    <a href="/not">important</a>
  </li>
</ul>

li.active a:before,
li a:hover:before {
  transform: scaleX(1);
}

This is very reduced, but it captures the essence. The navigation elements have some active style which should be applied whenever the user currently is on the indicated page or hovers the navigation link. What aspects can be improved using SASS? This was my first approach:

li {
  &.active {
    a:before {
      transform: scaleX(1);
    }
  }

  a:hover:before {
    transform: scaleX(1);
  }
}

This compiles to the desired CSS rules, but what did I gain? This is more code and more complex, so there should be a benefit too. The reason why I intuitively go with nesting is that rules are easier to move around. Changes in the HTML structure can be accounted for much easier, by just nesting a level more or less or changing li to another selector for example. But this is not very valuable in this case, a standard WordPress navigation’s markup will probably look the same forever. Moreover, there is a fundamental drawback with this way of nesting: The active styles have to be defined twice. It might seem obvious or pedantic to you, but it violates the single source of truth principle. Changing active styles is more prone to bugs, because someone might forget one or the other rule (If you are thinking mixin right now, wait for the last paragraph). So I tried another nesting structure:

li {
  &.active a,
  a:hover {
    &:before {
      transform: scaleX(1);
    }
  }
}

This again compiles to the same two CSS rules and defines the active styles in a single place. The nesting of selectors does not directly reflect the HTML structure anymore, but I am much happier with this solution. I guess one could argue either way, but I think in this case the second one is strictly better. But the lesson that I learned is that different SASS nesting structures usually represent different tradeoffs.

Writing it down made me realize that this would be a good use case for a mixin. The active styles could be defined as a mixin which can be called in two places in the first nesting structure. Usually I avoid mixins because I think it is very easy to over engineer in SASS without any real benefit. But I might actually switch to a mixin in this case. Anyways, that is it for SASS nesting. Takeaway: consider multiple nesting structures and evaluate their tradeoffs.