Stop using so many Sass variables
I used to write Sass that looks like this:
color: $body-text-colorpadding: $sidebar-padding
I don't like it any more. Now I love Sass that looks like this:
color: $hot-pinkpadding: 20px
The first is an example of abstracting the actual value away from the place you're using it, with a more generic, semantically-named variable in its place.
This approach has many fans, especially when it comes to colours. Here's a simplified example from Sacha Greif's post on the topic:
$blue: #00f$red: #f00$text-color: $blue$link-color: $red.foocolor: $text-coloracolor: $link-color
After doing things like this for a while, I've found that it doesn't make long-term maintenance easier and actually slows down development.
It depends what you mean by "semantic".
For a variable name to be semantic, it must convey useful meaning. For me as a developer, this is anything but semantic:
.sidebarcolor: $sidebar-text-color
$sidebar-text-color
doesn't add any value or meaning that I can't already infer from the selector and property name. It's just repeating information.
To get any meaningful information I need to follow the chain up to one of the two other places that define this value:
// _color_palette.sass$hot-pink: #bc436c// _config_variables.sass$sidebar-text-color: $hot-pink//_sidebar.sasscolor: $sidebar-text-color
That might not sound like much, but multiply it out across your whole project and you get a lot more development overhead.
On the other hand, take this example:
.sidebarcolor: $hot-pink
Immediately there's more useful information available. $hot-pink
still abstracts away the meaningless machine-friendly colour code, but adds more meaning for the human developer.
Plus, it's only defined in one place now if I want to see the actual value:
// _color_palette.sass$hot-pink: #bc436c//_sidebar.sasscolor: $hot-pink
But isn't that a maintenance nightmare?
The common argument goes like this:
What if I want to change my text from hot pink to forest green? I can't just change
$hot-pink
's value to green. That makes no sense!
Agreed. So instead of adding a layer of abstraction that doesn't really do anything to solve that problem, just add the new colour to your palette and update the value where required instead:
// _color_palette.sass$hot-pink: #bc436c$forest-green: #0c5c19// _sidebar.sasscolor: $forest-green
Ok? Ok.
But what if I need to update the colour in multiple places?
Update it in multiple places, it's really not that hard.
I can't think of a time when I've wanted to change a value globally across my stylesheet, regardless of where it is used.
I spend the vast majority of my time inside individual modules. Modules are standalone and independent, so I can't think of a case where I'd want to say "change this value wherever it appears in any module".
Theming
If you generate multiple themes from a single stylesheet or reuse a module across different stylesheets, variables are great! In that case, $sidebar-text-color
is genuinely variable, it's not just a global constant with a different name, so I'd totally do this:
// _normal.sass$sidebar-text-color: $hot-pink// _christmas.sass$sidebar-text-color: $red// _halloween.sass$sidebar-text-color: $orange// _sidebar.sasscolor: $sidebar-text-color
But how often do you really need to do this? It's pretty rare for me.
Summary
Nicolas Gallagher told us a year ago that content-derived class names aren't always the most useful names for developers, but we're still carrying all that baggage from when we were told that .bold
and .red
were grounds for expulsion from web development.
Abstracting reusable colours away into human-readable variables, like $hot-pink
, is awesome and recommended.
However defining a whole other set of variables with content- or module-derived names...
Doesn't make long-term maintenance easier. If I need to change a colour in a module, it's easier to just update a human-readable value right there in the module.
Slows down development. Finding or creating a global variable every time I add a
color
orbackground
property to a ruleset is painful.
If you take this idea beyond colours, you might end up with:
.sidebarbackground: $sidebar-background-colorcolor: $sidebar-text-colorpadding: $sidebar-padding-valuetext-align: $sidebar-alignment
And that doesn't look like much fun at all. I'd much rather author and maintain this:
.sidebarbackground: $greycolor: $hot-pinkpadding: rhythm(1)text-align: center