This is an old post from 2014. As such, it might not be relevant anymore.
My stance on CSS preprocessors in the past has been far from glowing, but I’m slowly coming around. Slowly being the keyword. But I’m there now, I love it. I used to think it was just because of variables, but actually the syntax is nicer than CSS. There, I said it, humble pie. And it’s not just because it’s leaner, it’s actually more maintainable, and I’m going to give you three quick examples why.
I used to write CSS on one line, and then indent the next if it was a child of the previous element. This worked really well and helps to understand inheritance and the way the markup is structured, and means you can see as much CSS on the screen at once as possible. I’ll give you an example:
<div id="header"> <div class="foo"> <p> <span>Lorem ipsum</span> <a href="#">Link</a> </p> </div> </div> #header{...} #header .foo{...} #header .foo span{...} #header .foo a{...}
However, if I now come to change the ID to something different I have to do it on every line. And if I have to change every line that means git has to track that. And if git has to track all those lines, then anyone else making a change means there will be conflicts. As such, it’s no longer a viable option: git should be able to tell you exactly what has changed, without confusion or conflicts for the tiniest change. With SASS this now looks like:
#header { .foo { span { ... } a { ... } } }
Changed a element ID/class? Obvious. Changed a property? Obvious. No longer need to sift through the line comparing what had changed manually.
It’s also less code to write, notice that I haven’t had to write #header .foo{…}, I just need to ensure it’s nested correctly. Of course this still gets compiled to the exact same CSS as the first example, so the output is the same.
When you have a large CSS code base, as we do at Ents24, you really want to separate each component into their own respective file. Need to update the navigation? Head on over to nav.scss. The footer, well, that’s in footer.scss! I know that you can do this in CSS with @import, but that’s a new HTTP connection right there. Have 10, 20, or maybe even 50 of them and suddenly you’re in trouble. Yes, you could minify the files together but that’s still a bit of a hassle. It’s far easier to let SASS do it, and when you have multiple projects which all pick-and-chose the components, it’s a no-brainer.
You can have a master CSS file per project that is essentially a list of @import‘s for each component it requires. Each of those components come from a compiled SASS file, and each of those SASS files can make use of a single base file, variable file, and mixin file to make everything streamlined across your project. For instance, consider this folder structure:
`- sass |- _base.scss |- _variables.scss |- _mixins.scss |- grid.scss |- header.scss |- footer.scss |- nav.scss |- button.scss `- table.scss `- css |- grid.scss |- header.scss |- footer.scss |- nav.scss |- button.scss `- table.scss `- project |- desktop.css |- desktop.min.css |- mobile.css |- mobile.min.css |- widget.css |- widget.min.css |- foobar.css `- foobar.min.css
The sass folder will contain the files you edit, these are then automatically compiled down into their respective files in the css folder (the SASS files with an underscore will not get compiled!), and when those files are updated they will trigger the project files to be updated, and then those will be automatically minified for you to use in production.
You can hopefully suddenly see the huge benefits. desktop.css and mobile.css might actually make use of each of the CSS files, but the widget project might be a tiny thing that people can add to their own sites, and might only require the grid.css and button.css files. You’ve now a consistent brand feel across everything you do for free, and with ease of maintenance. Win.
And lastly we come to mixins. These are small snippets of CSS which are frequently used throughout your codebase which are often annoying to write. An example of this is rounded corners. Remembering each vendor prefix is a pain and quite honestly I can’t count the number of times I’ve simply used border-radius in isolation and forgotten about old browsers. Update: Although a good example, this is probably bad practice now; you shouldn’t really use vendor prefixes too much, let older browsers degrade nicely.
We can define our mixins in our mixins.scss file, something like:
@mixin border-radius($radius) { -webkit-border-radius: $radius; -moz-border-radius: $radius; -ms-border-radius: $radius; border-radius: $radius; }
And then make use of them in our SASS files:
#header {
@include border-radius(10px);
div {
@include border-radius(8px);
}
}
This saves us a huge amount of time, makes things easier to maintain, and also gives us a single place to contain horrible things like vendor prefixes, so once you no longer need them you can easily switch them out.
I could have talked about variables, but you already know about them and how they make things easier. I could have talked about how you can easily make drop shadows just by using darken($color-x-feature, 10%), but that’s something for you to learn on your own… wait, I just did. I’m trying to say there’s a lot more to SASS than variables. If you’re a project manager or team lead and you’re looking to make your employees happier, more productive, and your codebase more maintainable, then you could do a lot worse than having a quick look at SASS.