Thursday, August 7th, 2008

CSS variables considered harmful?

Category: CSS, Standards, W3C

<p>

Bert Bos, a W3C fellow, thinks that CSS variables are to be considered harmful:

Adding any form of macros or additional scopes and indirections, including symbolic constants, is not just redundant, but changes CSS in ways that make it unsuitable for its intended audience. Given that there is currently no alternative to CSS, these things must not be added.

He has some very compelling points in there, some of which I agree with, and others that I don’t:

This PHP version proves that it is not necessary to add constants to CSS. Just like the existence of the WebKit implementation cannot be taken as proof that constants in CSS are useful, so the PHP implementation cannot prove that either. But the PHP implementation has the benefit of letting authors determine the usefulness for themselves, without modifying CSS on the Web.

You can obviously use pre-processors to do many macro situations. This doesn’t mean that it is the right place for functionality like this. I don’t want to force every CSS request through PHP. I also like having functionality in CSS itself, as that can be shared across projects and developers without “oh, and by the way this looks a little different as we pre-process it with a magic Rails action”. Something as important as variables should be low level IMO.

It is quite likely that somebody who is trying to learn CSS will give up learning it when he sees that style sheets that occur on the Web don’t actually look like the tutorials he started from. Difference in upper- and lowercase or in pretty-printing are hindrances to learning, too, but limited ones: you soon learn to ignore those differences. But symbolic constants are different in each style sheet and have to be interpreted and understood each time anew.

A touch too strong. Things change. Tutorials get out of date. C’est la vie. And, you can always use old form…. and the feature is so simple that it won’t take you weeks to work it out!

People who understand CSS in principle may still have trouble understanding the indirection provided by the em unit, many have trouble with the advanced selectors in level 3, and many more won’t understand, e.g., any of the properties that have to do with bi-directionality or vertical text. For each feature that is added to CSS there must be a careful balance (based on an informed guess, because these things are difficult to test) between the number of users that will be excluded by that feature and the number for whom it is essential that it be added.

I agree in the balance. There are some crazy complicated parts of CSS. However, simple variables is trivial in comparison! Also, I think it will be used a hell of a lot more frequently.

Treating symbolic constants as an independent module would make them available for use in other contexts than CSS, would make them available to precisely the people who need them without hindering other people, would allow them to be developed without impact on CSS, and allow them to be developed more easily into what they are sure to develop into anyway: full macros, able to replace anything, not just CSS values, and able to make files shorter instead of longer.

I agree about modularity. There will be issues with scope and such, and we will have to fight to keep the system as simple as possible.

However, I can’t wait to be able to re-skin something by changing the variables only that represent semantic parts of my application. Search and replace isn’t good enough. Having tools that see the #xxxxxx and show you a color aren’t good enough. You end up reading a lot more CSS than you write, so we should help that use case. I don’t think CSS should become a programming language with if statements and the like, and I doubt this is a gateway drug to that.

Related Content:

  • Hard Times
    For many, the era of champagne receptions has long since passed. But where else can costs be cut without harming the...
  • Escaping Properties Purgatory
    Throughout Java's core API, properties are used to give users and administrators more control over their applications. Consider the following three...
  • Understanding the User Experience
    The most critical event in a project's life is when users get their glimpse at it in production. Though they may be seeing all of the functionality...
  • Testing Web services and RIAs
    The component nature of Web services and RIAs can lead to testing headaches. This tip shows how Firefox, Apache and soapUI testing tools can be...
  • RPG application modernization for i5
    RPG application modernization offers some serious benefits for System i. Learn some modernization strategies that don't upset the apple cart and...

Posted by Dion Almaer at 8:06 am
24 Comments

++++-
4.3 rating from 22 votes

24 Comments »

Comments feed TrackBack URI

I think the CSS concept is broken, only on the web would you see such a styling mechanism for a document. If JSS was cleaner back in the day it would have been preferable (Maybe a JSON style object structure?). At least all your mental eggs would be in one language basket, lowering the learning curve significantly. (It no doubt would have made manipulating a stylesheet at runtime a hell of a lot easier too)

Comment by TNO — August 7, 2008

I like the idea of CSS variables, but I think something else is much more important.

It would make much more sense to allow inheritance. Then, any definition in CSS could be based on another. While you can already do this manually by adding extra class names to the class=, it would be drastically simpler if you could do this from within CSS itself.

Variables may still be useful in some circumstances. For instance, if the same color was to be used for one element’s border color and another’s background color, it could then make sense to use a variable.

As for preprocessors, I actually think that they are a wonderful idea, and not just for CSS. The current web platform absolutely sucks; HTML was never meant to be used for what it is being used for today, and CSS, while very powerful and relatively well designed, was basically shoe-horned in to the existing, poorly-implemented and poorly-designed system to add extra functionality. (Though, I will admit, JavaScript is a great language).

It makes no sense, therefore, to directly write HTML, CSS, and JavaScript code in the way we currently do. A preprocessor could allow platform-independent code to be written once, and have the preprocessor format it into HTML and CSS. It appears to me that some people have already done this; I’m not certain, but it appears as if that is what Google Web Toolkit and that Objective-C implementation are meant to do.

It was mentioned a few days ago that it takes too long for the web platform as a whole to adopt changes. Imagine how, here as well, a preprocessor would be useful: the preprocessor could handle graceful degradation in many circumstances. For instance, say if you wanted some object to animate moving from left to right. You’d tell the preprocessor to animate the object from the left to the right. The preprocessor would determine if the target system allowed Webkit’s transitions, and if so, use that; otherwise, it would write some JavaScript instead. For some features that some browsers may not implement fast enough, the preprocessor can implement instead. New features could be delivered very quickly in this way.

In my mind, this kind of system is the future of the web.

Comment by ialexi — August 7, 2008

In a perfect world he would be right, but in the real world, for real web apps, he’s wrong.

IMHO, PHP is not the answer, because the performance overhead of launching a script interpreter every time a CSS file is requested is simply unacceptable given the current obsession with web app speed and the constant quest to shave off another few milliseconds in the loading time.

And as for the argument that constants aren’t needed because CSS files are short, that’s simply not true. CSS files may be short, but there are often dozens of them in large projects. When you make a style change, you need to change all of these files, and then you need to also change every line in the file where the styles are used. It would be much better to have one CSS file that defines constants, and then have all the other CSS files build on top of that.

Worse still, because CSS cannot separate colors from layout without the css constants feature, it does not lend itself as well as it should to themeing, which makes no sense, because themeing is THE real-world reason to separate style from content.

Comment by Joeri — August 7, 2008

@TNO: re: inheritance, you can use commas, comments and CSS minifiers/compressors.

@Joeri: you can create a static CSS file via PHP, and save it on disk so that the preprocessing only happens once during development and never on a live site. Variables (despite the misleading name) are unlikely to change in CSS.

I dislike the idea of CSS variables simply because they add too much overhead in order to become understandable

Comment by LeoHorie — August 7, 2008

ops, my first paragraph was meant to respond to ialexi, not TNO.

Comment by LeoHorie — August 7, 2008

@LeoHorie:
If caching it on disk was that simple, we would all be doing it. These comments aren’t really the place to go into detail why it’s just not that simple, but well, it’s not that simple.
Your blog post is missing the point of what I (and I suspect others) want these for. I want to do something similar to how the windows color scheme works. You define a small set of a few dozen color variables, and you reuse these throughout all your different controls where they make sense. CSS classes just don’t cut it for this (and believe me, I’ve tried to make them work for me).

Comment by Joeri — August 7, 2008

I love that variables are too complicated, but the inline formatting model is not. JavaScript has been made ten times more useful recently by frameworks, but CSS frameworks will never be really useful until some generality and composability is allowed in CSS. We need basic power in the language, not border-radius or drop shadows.

Comment by K9 — August 7, 2008

We sort of already do have these variables for colors, or maybe they are best described as entities… I can say a color is color:#FFFFFF, but I can just as well say that it’s color:white, color:aqua, color:FireBrick, color:CornflowerBlue.

So why shouldn’t I be able to define these and make up new ones as I define entities in an XML or XSL document? I think newcomers to CSS are able to understand color:white… so why not be able to have color:basetone and color:accents.

That is what seems to me the most natural direction. Of course it’s very specific to colors… but on the flipside it’s not like there’s a huge demand for variables either and this one would actually have a “type”.

@TNO
I think you mean JSSS…
Doesn’t it lack any control on nodes other than their node names?
It’s extremely laborious to hand code or read because of it’s one line declaration for each node attribute.
Maybe it’s got variables and expressions but without access to Classes and IDs or any other label than the tag names… it won’t be doing anything productive with those variables.

Saying CSS is broken is a pretty bold statement and you don’t say why it is… CSS does what it’s supposed to do and very well.

Comment by JeromeLapointe — August 7, 2008

@LeoHorie: Re: inheritance: First, proper inheritance is not (from what I’m aware of, at least), possible in CSS. You cannot make one class inherit from a class defined in another file. If you could we could better separate CSS for layout and CSS for styling (which would allow much smaller CSS style files).

Still, I take back a bit of what I said regarding inheritance earlier. My biggest problem with CSS variables is that they appear to be declared in some sort of global scope, and to me, this seems to be a big no-no. I liked the idea of inheritance because it would allow a much more organized way of storing variables.

An even more organized way, however, could be very simple in concept. Imagine the following code, which illustrates the possibility of inheritance and a better variable scheme (forgive me any errors — I am a tad rusty at the moment, and also forgive the absolutely terrible color scheme):


.myColorScheme {
keyColor: #0000FF;
accentColor: #FF0000;
}

.boxElement
{
backgroundColor: myColorScheme.keyColor;
color: accentColor;
border: 1px solid myColorScheme.accentColor;
}

/* In another file */
#navigation {
inherit: boxElement;
float: left;
display: block;
/* Other layout code here */
}

This really is not against how CSS is defined; .myClassName selectors aren’t really selectors, but class definitions. It only makes sense to be able to use the content of those class definitions later.

The inheritance I show would simply insert the properties defined in the class to inherit from into the class inheriting; you could even make one class inherit from another multiple times, but if you did, it would probably mean that you designed your CSS poorly.

Comment by ialexi — August 7, 2008

I think that CSS is a good language because of it’s standalone approach. You don’t have includes, import (at least not in the Java way); you don’t have to care if some other file was loaded, if some other part is already defined (except for inheritance purposes), your only effort is totally focused in organization and inheritance of your classes / ids / other selectors.

IMO, no matter how pretty could be that so-beloved / so-hated CSS “vars”, it would introduce problems more related with programming, rather than styling (like var scope, fallback behavior, undefined vars, etc).

And, also, these vars are a requirement that comes only from a small part (IMO) of web developers / designers / whatever. You can use, currently – without worrying about when will incorporate a new CSS capability, things like

.my-pretty-class{color:red;}
.asd{background-color:white;}
.dsa{background-color:orange;}

I’m red
Me too

If you really need an universal property.

Comment by HudsonTavares — August 7, 2008

Just a correction: On my comment, above, both the “I’m red” and the “Me too” texts are inside of paragraphs, the first using the classes my-pretty-class and asd, and the second using my-pretty-class and dsa.

Damn XHTML strip.

Comment by HudsonTavares — August 7, 2008

I’ve wanted variables in css for at least 8 years. Simply put, going from the font tag everywhere to being able to style p’s was a huge improvement. I could alter the style for all the p’s in one place. But in css itself we still have the ‘font tags everywhere’ problem where we’re trying to implement colors from a style guide. Say body text, input borders and nav background are #333. That’s 3 sets of selectors and rules I have to set up for 1 piece of data. If the styleguide says those 3 things will always be the same color, even if that color changes, I should be able to set that color in one place. It sounds as if Bert is coming from more of a CS background than a design background with this argument. Styleguides have constants. One of their primary functions is the expression of constants. And having to hard code values all over the place is a major shortcoming of css as a style language. Maybe not so big a deal if you’ve got 30 lines of code in your styles. But it’s common for our projects to have 3000 lines of code in styles. Also, php and javascript aren’t viable workarounds all the time. Sometimes you don’t have javascript available to you. Sometimes it’s a flat site and you can’t have a backend. And even if you could depend on those all the time, we’re supposed to be separating markup, style and processing. Using js or backend processing to make something happen in css is antithetical to this separation. And as far as harm… you could always choose not to use a variable and roll old-school.

Comment by tack — August 7, 2008

variable scope: This is one of the cases where global variables are a desired functionality. We aren’t doing processing here. We aren’t worried about function A overwriting a global then function B breaking. Everything should be static. That being said, being able to specify a variable in the styles for div#myWidget so that div#myWidget p can use it but, say body can’t should be all the localization we need. I don’t see a case for doing object/class inheritance in css. This isn’t OO programming. This is describing style rules. Even though we’re skilled in the fine art of using a hammer, this is no nail, it’s a screw. And we should leave those techniques to the processing side of things (js and backend)

Comment by tack — August 7, 2008

“This PHP version proves that it is not necessary to add constants to CSS. ”

This is a ridiculous claim. It’s like saying there’s no use for higher level programming languages (or CSS for that matter) because I can just write assembly.

Comment by tlrobinson — August 7, 2008

@tack: I agree that sometimes, in some use cases, a CSS var could be very suitable.

However, I disagree at the point you said “it’s common to have 3000 lines of CSS code”; I’m doing nice / responsive / complete sites using less than 400 (the site that is opened right now on my Dreamweaver’s window have less than 200) lines.

Your site’s complexity / size might not be (and very, very often, isn’t) proportional to the amount of CSS styles you have to write.

@tlrobinson:
You’ve got this phrase out of it’s context. The complete paragraph says:

“The other implementation is written in PHP. It proves that it is not necessary to add constants to CSS. Just like the existence of the WebKit implementation cannot be taken as proof that constants in CSS are useful, so the PHP implementation cannot prove that either. But the PHP implementation has the benefit of letting authors determine the usefulness for themselves, without modifying CSS on the Web.”

BTW, LOL, hyperbolic example.

How much similarity is shared between a language resource and programming languages from completely different levels you see?

Comment by HudsonTavares — August 7, 2008

Double-posting, again:
How much similarity is shared between a language resource and programming languages from completely different levels?

Comment by HudsonTavares — August 7, 2008

>> If caching it on disk was that simple, we would all be doing it.

@Joeri: Well, we are doing it, or at least we should be. We can only serve static CSS content, so I really don’t see any reason to dynamically generate a different stylesheet for every page. The YSlow performance tips go into the details fairly well.

As for aliasing, like take mentioned (e.g. CustomRed = #ff0010), it can be pre-processed and cached fairly easily… The code to do it with PHP is just a dozen of lines long, if that.

@ialexi: you’re right, OOP-style inheritance isn’t possible in CSS because it’s not a object oriented language in the first place. Stylesheets are a bunch of queries, and the objects to which the queries apply live in the HTML. I consider CSS much more similar to SQL UPDATEs than to Java.

Comment by LeoHorie — August 7, 2008

@JeromeLapointe:

I’m not saying we should run back to the original specification of JSSS, but I think the current concept has too many flaws, and too much complexity already. I don’t want to get off topic, so here’s a few links that describe the problems pretty well I think:

http://www.cybergrain.com/archives/2004/12/css_considered.html
http://www.accidentalscientist.com/2007/07/css-sucks-for-layout.html
http://www.nczonline.net/blog/2007/10/8/css_sucks
http://gui.net/blog/2006/12/15/why-css-sucks/
…and the list goes on

Comment by TNO — August 7, 2008

@LeoHorie: my point was that if dynamically generating a stylesheet is so simple, everyone would be doing it. You need a design-time build system, or you have a run-time overhead from starting the interpreter. Both of those are so non-ideal that neither is in common use.

Really, css variables are the cleanest solution to the problem of reusable style definitions. Why is that such a hard concept to grasp?

Comment by Joeri — August 8, 2008

@LeoHorie But what I suggested was not quite object-oriented-programming-style inheritance. I suggested being able to “import” one style into another, creating an effect similar to inheritance, but not actually inheritance.

I realize that stylesheets are collections of queries, and as such, perhaps the “inherit” statement should allow the use of another selector, rather than a “class definition” as I called it earlier. This has a large potential for abuse, but a large potential for proper usage. It would run something like this:


.myBaseSelector
{
color: white;
}

.myBaseSelector div
{
backgroundColor: "black"
}

.myNewSelector
{
inherit: .myBaseSelector;
/* BAD (but valid) USE: */
inherit: .myBaseSelector div;
}

Comment by ialexi — August 8, 2008

@TNO
Well your first link basically says CSS is too complicated for designers. That maybe but then adding variables would not simplify things for them (nor making it JS like)… but CSS is not a design tool either. No wysiwyg editor will ever put out sensible code anyways…. independently of the language that’s running behind it.

Your 3 last link are really just disputing the role of CSS as a layout language… which is an old debate that basically comes down to columns. It always seems accompanied with a nostalgia for the old days of table layouts. Table design is a failure. There is room for bringing columns to CSS, it just needs to get implemented.

In any case the people who have a problem with CSS for layouts usually want to add another layer of tech… which does nothing to bring all the “mental eggs in one language basket” as you say.

Getting back on topic.
It seems to me (I may be wrong) that the main request for CSS constants (or variables) comes from app builders who want a more dynamic CSS for their widgets and apps. I get that, but it’s very specific. It gets even more specific when you realize most of them are talking about colors and nothing else. In fact in most cases, you could use constants to accomplish the same thing.

As I was saying earlier, most browsers support the “named colors” and “system colors”. The W3C refers to them as keywords.
http://www.w3.org/TR/CSS21/syndata.html#keywords
“A is either a keyword or a numerical specification.”

What would be cool is if you could declare your own “keywords”.
I can already go:
.myApp{color:redbrick;}
.myApp{background:ButtonFace;}

so why not simply allow me to do:
@colors{myAppBasetone:#FF0099;}
.myApp{background:myAppBasetone,#F09;}

(notice the “font-family style” backup color)
This is something they could add to SVG & Canvas as well.

Comment by JeromeLapointe — August 8, 2008

@ialexi(alex)

I like your idea. An inheritance possibility in CSS would make everything easier. I have been thinking about this as well. However, let’s call this pseude attribute import, merge, use or mixin. Caling them classes or 00 inheritance in CSS often confuses people because they think that you want to implement complex OOP concepts whereas we only want to achieve something simple: namely, the overlay/overwrite (top-down) of CSS class attributes using a CSS selector for a different CSS class in a CSS document.

Many people say that we already have this in CSS, which is basically true (whitespace seperated class name list). However, the inheritance definition is shifted from the CSS document into the HTML document. Which means that, if I want to achieve a relatively strong abstraction of CSS styles in CSS, I have a long list of class names in the HTML document element class attricute. Firstly, the document gets too large and secondly, one always has to remember the whole chain of the inheritance hierarchy.

Especially the latter causes lots of trouble. We have two or more people working on the CSS/HTML at the same time, and each of them needs to have a good overview of the CSS definitions and has to speak often to the other developers, otherwise, they define things twice which is unnecessary. In large projects, it is almost impossible to keep a clean CSS in the long run.

On the other hand, you would put the inheritance (merge, mixin, import) back into the CSS document if you worked according to the blackbox principle as a developer. I only have to know the base classes (definitions), I can import/mixin/merge this base class to my new class and overwrite only the necessary attributes in this new class. In the end. I only have to know thes one new special style class and I can hand it over to other develpers. Then, they can overwrite the class again. furthermore you achieved an improved recycling of style definitions.

I hope all cann follow me. I’m not a native english speaker.

Comment by jfw — August 9, 2008

I’m the author of the PHP version.

I just want to correct some incorrect assumptions about how it works.

It doesn’t process it every time, it only will process if the css stylesheet has changed, and there is a command line compiler so you can precompile everything.

The PHP version actually is built to the same spec that the webkit version is, the stylesheets are interchangable. I implemented it this way so that when browsers catch up, those stylesheets would be usable without change.

The one difference between my implementation and the spec, however, is that I have an eval() that lets you do stuff like:

padding: eval(variable / 2);
margin: eval((anothervariable / 2) * yetanother);

Honestly, I don’t give a shit if people use it or not, we use it at massify.com and have found it an incredible boon to productivity in regards to how we build some very complicated pages and keep consistency across the entire site. YMMV.

Best,

Jon.

Comment by IFlyHigh — August 9, 2008

Use SASS if you definitely need those variables.

Comment by cheba — August 27, 2008

Leave a comment

You must be logged in to post a comment.