Sass was, to me, as big a revolution to my web development workflow as changing from tables to CSS for layout way back in the day. Variables, functions, nesting and more are powerful tools I never took the time to want from CSS, but once I had them, couldn't imagine working without them!
A big benefit of Sass is the reduction of your CSS files. But if you're unaware, one of Sass's time-saving features, the
@extend directive, can bloat your resulting CSS file worse than an overzealous truck driver comically over-packing his vehicle (segue!). Here is the issue I discovered and how to fix it.
Quick intro to the @extend directive
@extend combines the current selector with that of what you're extending to reduce declaration repetition. It's pretty straight forward, and the best way to illustrate is with an example:
But our stylesheets are more complex than that.
Let's adjust things a bit. Buttons in forms and the sidebar need to be blue. And I'm using a jQuery plugin that generates its own classes, so I can't use my
.button class. But because Sass is awesome, I can just extend my class! Here's where the trouble comes in. The resulting CSS isn't what you might expect:
CSS (657 bytes)
Check out those CSS selectors. We have all kinds of combinations we don't need. I don't know about you, but I find
.sidebar .slideshow .js-plugin-link highly unlikely. This mess is happening because we are reusing the selector we're extending.
.button is used three times and extended twice and Sass is trying to extend all three of them both times.
There is another way.
Placeholder selectors are the perfect solution to this issue. These take the place of a selector and can be extended without consequence. If a placeholder selector is never extended, it will never appear in the CSS. You could have an entire file full of line after line of placeholder selectors that would just be invisible in the end if they go unused. So how do we fix our button problem? Like this:
CSS (363 bytes)
If you didn't need the actual
.button class in the markup, you could remove that entirely.
I've gotten to where I almost exclusively
@extend placeholder selectors for the very reasons outlined here. As a result, my CSS files are much cleaner and a bit smaller.