Tuesday, August 5, 2008

Why CSS Variables are harmful : the pragmatic answer

So, everyone seems to be commenting on this piece about why CSS variables are bad. It talks a lot about the learning curve issue. Quite frankly, I personally think that's irrelevant since CSS is far from having a challenging syntax. But, I do think variables have their issues.

The Issue: naming conventions

Assuming we are all sane people who don't name our variables "abc123", there are two naming conventions that we can use for CSS variables and I think they are both horrible.

Consider this snippet (which uses the syntax proposed here):

@variables {
  CorporateLogoColor : red;
  TitleColor : blue;
  TitleFontSize : 16px;
  LinkColor : green;
}
h1 {background : var(CorporateLogo);}
h2 {color : var(TitleColor); font-size : var(TitleFontSize);}
a {color : var(LinkColor);}

Look closely at the rules above. How many of them can you honestly call "reusable"? Using the CorporateLogoColor variable to define the font color of footer text or image borders is obviously not a good practice. Likewise, reusing any of the other declarations will just cause a lot of confusion later on. This happens because the variable names are being used to describe the values they reference. We're effectively saying "This 'blue' is not just any blue. It's a Title Color".

I really don't see any reason to create an alias like this. If the class name is descriptive enough, I really don't need to re-describe it. And I could very well use comments if my class name wasn't descriptive.

If the variable name is too generic, it will invariably need to be overwritten by more specific rules (e.g. BGColor vs. ContentAreaBGColor). If the variable name is too specific, it will be bad practice to reuse it when it doesn't describe its purpose (e.g. BGColor being used as a link text color). Perhaps worst still is that I'll effectively need to double the amount of text that I have to type and that users will have to download. Weren't CSS variables meant to accomplish the exact opposite?

Ok, so the semantic approach fails, how can it work?

Well, how about we do this:

@variables {
  Vibrant : red;
  Cold : blue;
  Big : 16px;
  Interesting : green;
}
h1 {background : var(Vibrant);}
h2 {color : var(Cold); font-size : var(Big);}
a {color : var(Interesting);}

This is certainly more reusable, but I can argue that "blue" and "arrow.gif" are more than appropriate for describing things that are supposed to look blue or look like arrows. This approach is prone to the old problem with using values as class names in CSS: with the current spec, if you have a undecided client, you can end up with:

.red {color:blue;}

And likewise, with variables, you could end up with:

@variables {
  Arrow : url(circle.gif);
}

The main difference to note here is that semantically descriptive class names are considered good practice, and descriptive variables, as I've shown above, are counter-productive.

The abstraction argument

Ok, we could go and change "Arrow" to something more generic. "Bullet", for example. After all, this graphic will most likely be used to style variants of "ul li".

The problem is that we will still run into duplication issues:

a.learnMore {
  background:url(arrow.gif) no-repeat 100% center;
  padding:0 15px 0 0;
}

It's pretty obvious why "Bullet" doesn't work here.

Well, so variables suck, right?

I can see one use for them: aliasing. This makes sense:

@variables {
  Arrow : url(files/images/ui/icons/generic_arrow.gif);
}

But let's be thorough. The following is a waste of time, since the alias ends up being longer than the original value:

@variables {
  VibrantRed : #f00;
}
/*compare:*/
a {color:#f00;}
a {color:var(VibrantRed);}
/*note that the 2nd line needs the
@variables declaration in addition to
being more verbose
*/

Last thoughts

I find that most people I meet who like the idea of CSS variables have predominantly imperative programming backgrounds, so I'll just say this as a semi-rant: Look, CSS is not Blub, it's a DSL. It will never be the same as your turing-complete language of choice because it serves a different purpose.

If you find that maintaining your CSS is hard, chances are that you're writing it wrong. Learn to use the comma.

No comments:

Post a Comment