I used to write Sass that looks like this:
color: $body-text-color padding: $sidebar-padding
I don't like it any more. Now I love Sass that looks like this:
color: $hot-pink padding: 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 .foo color: $text-color a color: $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:
.sidebar color: $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.sass color: $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:
.sidebar color: $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.sass color: $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.sass color: $forest-green
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”.
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.sass color: $sidebar-text-color
But how often do you really need to do this? It's pretty rare for me.
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
.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
backgroundproperty to a ruleset is painful.
If you take this idea beyond colours, you might end up with:
.sidebar background: $sidebar-background-color color: $sidebar-text-color padding: $sidebar-padding-value text-align: $sidebar-alignment
And that doesn't look like much fun at all. I'd much rather author and maintain this:
.sidebar background: $grey color: $hot-pink padding: rhythm(1) text-align: center