What CSS is missing
It appears that CSS 3 will be the final iteration of the language. Undoubtedly, there’s some cool layout stuff in there along with everyone’s favorite tricks like rounded corners and opacity. However, I’m pretty dismayed if this is the end of CSS because I think there’s a very important concept still missing: variables.
I, like many designers, find myself using the same colors in multiple places throughout a style sheet. Consider:
div.container {
background-color: #123456;
}
div.outer a {
color: #123456;
}
These two rules each use the same color, but in different ways. This means that the rules can’t be combined for simplicity. The fact that they both use the same color is irrelevant as far as CSS is concerned; there is no relation between these two rules. I say this is ridiculous. The next time I want to change the style on this page, I need to manually search and replace each instance of this color. Okay, maybe I’m going a little overboard, you can use the replace functionality of any basic text editor to do it but the issue I’m looking at here is the relationship between these two rules.
If CSS had some support for variables, style rules could be given some greater semantic value aside from listing out explicit details. Consider if the following code was possible:
@define {
$highlight_color: #123456;
}
div.container {
background-color: $highlight_color;
}
div.outer a {
color: $highlight_color;
}
With this code, you can tell how each rule relates to the overall page style. This approach can be done using server-side languages, intermixing variables with CSS…but that creates a layer of complexity that I’m not sure is necessary for most sites. The simple fact is that I want to be able to define colors (and fonts, and other information) as relevant parts of my page’s look and feel, not simply hex numbers or other measurements that don’t speak to me. Am I the only one who thinks this could be a great addition to our toolkit?
Disclaimer: Any viewpoints and opinions expressed in this article are those of Nicholas C. Zakas and do not, in any way, reflect those of my employer, my colleagues, Wrox Publishing, O'Reilly Publishing, or anyone else. I speak only for myself, not for them.
Both comments and pings are currently closed.




16 Comments
I think its a great idea, aswell as the expression implementation that we have in IE/Trident browsers.
I really enjoy the possibility to mix CSS and JavaScript, and also define variables!
Can you imagine:
@define {
$page_width: expression(window.innerWidth || document.body.clientWidth || document.documentElement.clientWidth);
$page_height: expression(window.innerHeight || document.body.clientHeight || document.documentElement.clientHeight);
}
DIV.content {
width: expression(Math.max(400, $page_width) + "px");
height: $page_height + "px";
}
Wow… what a powerful idea! =D
Guilherme Blanco on January 25th, 2007 at 9:54 pm
This idea has been tossed around before and is becoming somewhat of a religious issue.
I don’t see the need for variables to do things like colour in CSS. People seem to forget the ‘Cascading’ part of CSS. You can happily define the colour in one place and other attributes else where. It’s not too hard to separate grid, colour and typographic CSS rules into separate sections. Then you only need to declare the colour in question once anyway:
div.container, div.outer a {
background-color: #123456;
}
Strange Pants on January 26th, 2007 at 6:42 am
I agree with you Nick…it should be there. I’ve said this for a long time and have read where the powers that be were gonna consider it blah, blah, blah.
I also get what you’re saying Strange Pants…and a lot of times, that works perfect. But there are plenty of times where I need to reference the same color or other attributes against different rules, like he has in his example, color on one selector, background-color on another. With something like CSS variables, you’d only have to declare that color once.
Oh well, the purists seem to rule, and that’s okay. They’ve done a pretty good job overall. Don’t think we’ll see mixed script and CSS Guilherme…that’s just plain crazy [totally kidding here, it would be handy] But first they’d have to change the rule about XSLT variables never being able to change!
Mike Shaffer on January 26th, 2007 at 9:19 am
@Guilherme: I personally don’t like JavaScript in CSS. Instead, CSS should have its own statements to achieve the same goals. For one, my stylesheet should have only CSS, not a mix of CSS and JavaScript. And two, performance. A CSS engine relying on a JavaScript engine isn’t very efficient, which is one of the reasons expressions in IE are looked down upon.
@Strange Pants: That is true; however, what’s the relationship between div.container and div.outer a? I don’t know about you, but I have my CSS grouped together according to their relation on the page. Sticking two elements on the same rule that have no relationship to each other is wacky to me. You wouldn’t do the same in any other language; why should CSS be different?
Jeremy on January 26th, 2007 at 9:39 am
I recently saw an article on 24ways.org this past December dealing with this exact issue. It suggests using server-side code to declare variables just like you suggested. Check it out:
http://24ways.org/2006/faster-development-with-css-constants
Kevin on January 26th, 2007 at 10:05 am
I also think there is need in CSS to be able to define something once and use it many times aftwards. Color is a good example because of branding requirements on any given site.
But rather than a ‘variable’ I would call it a ‘constant’. I don’t think we should be resetting this value somehow later in the page as the name variable implies. Instead I’d use the cascading nature of CSS to help assign a hardwired value or another ‘constant’.
hans brough on January 26th, 2007 at 12:25 pm
@Strange Pants – cascading doesn’t solve all of the problems I’m talking about. If you want to use the same color for text in one area, a background color in another, cascading doesn’t help.
@Kevin – I’ve seen this implemented before, and I’ve done it myself. I just think it’s something that shouldn’t require server-side logic.
@hans – You’re right, what I’m proposing are constants, not variables. I agree that they should not change during the course of the file.
Nicholas C. Zakas on January 26th, 2007 at 1:44 pm
Where did you hear that CSS 3 will be the last version of CSS?
At their glacial development pace, it might as well be.
Richard York on January 26th, 2007 at 2:56 pm
Nicholas
. Well, almost.
I find the example is not particularly convincing. I can assume that someone can use the same color as foreground in one place and background in another. But in any case they are two entirely different things and it is better to think of them respectively. I mean it would be better to use two different classes
.foreground { #123456; }
.background { #123456; }
and use them in appropriate contexts, than use ONE value for two ENTIRELY different properties and realize somewhere in the final development phase that you should change foreground color in some part of application, but you can’t because it would consequently change BACKGROUND in another part.
Maybe I am wrong but for me it just looks like common sense. Two entities – two declarations. No ambiguities. No need of constants.
But let’s put aside colors. Where else could such constants be applicable?
In my opinion CSS is beautiful, elegant and extremely flexible even in its current state. The only obstacle for me is support in major browsers. If I only could get rid of IE6 and add a few selectors and combinators to IE7 I would be completely happy
Alexei Gorkov on January 26th, 2007 at 4:01 pm
I agree NZC, at very least it would be great to be able to add to the list of predefined colors. We have a swatch of 5 colors we used primarily. With very large applications with complex CSS it would be impractical to try and apply these 5 colors using selector combinations in the way that some readers above have suggested.
Doing this server-side is a pain unless you are careful. You need to consider caching, setting the correct headers and will likely cause future problems when another developer fails to realise your CSS is served dynamically.
wioota on January 27th, 2007 at 12:58 am
@Mike and @Jeremy: I don’t think it’s the best idea. I just think it can be a powerful idea, we’re just dreaming.
Of course I prefer performance to resources. I just mentioned this, because since I’ve been known as a man, something like does not work weel:
.box {
position: absolute;
top: 10px;
bottom: 10px;
left: 10px;
right: 10px;
background-color: black;
}
It should work as everyone expect, a box fulfilling the whole screen, with a "10px border". This is not a good example, but I think you understood what I am trying to say.
As long as CSS processes rules reasonable, everybody will become happy. We do not need such hacks I mentioned, as long as what the language defines works. But they do not work, what can we do? Implement another hacks?
Anyway… CSS variable is a great addiction to be listed in their TODO. =)
But I still prefer a consistent behavior of current properties. I think you agree with my point.
Guilherme Blanco on January 27th, 2007 at 1:47 pm
@Alexei – what I’m looking to define here is the relationship between colors. Since there can be many parts of a page, simply saying "background" or "foreground" doesn’t have a lot of value. In terms of the overall style for the page, saying "highlight color", "shadow color", etc. has more value. For instance, the color of my page’s overall background is a shade of green. I also want that same color for links and the lines that form the columns on the page. The color is the same in all of these locations, that is, they have a relationship to one another. When designing a web site, we don’t think about the background being one color, the lines being one color, etc.; we think about which elements have the same color. All I’m asking if for CSS to act the way that we think.
Nicholas C. Zakas on January 27th, 2007 at 8:53 pm
Nicholas,
I am by no means insisting on my point of view, which is likely to be erroneous but still several arguments:
I understand the meaning of your example and of course the name of a class (or constant in your way) should be the one which better suits its purpose. Let it be highlightColor, shadowColor or some other.
But I cannot agree that “… when designing a web site we think about which elements have the same color.”
This idea just doesn’t comply with my everyday experience. For example, our team is working on quite complex and elaborate web application. Only during last year it underwent several redesigns (from simple change of color schemes to complete reconstructions). Of course we could select some colors that have the same value in different contexts (like color of a link, color of text, background color etc.).
What I am trying to say is that the relationships that the colors have in current color scheme and current design of some part of an application doesn’t necessarily (and actually according to my experience very rarely) remain the same in another color scheme or another design while hierarchical relations which are defined through CSS cascade and inheritance are rather stable and reliable.
On the other hand I can easily imagine which difficulties I would inevitably encounter if I used the proposed technique.
Let’s assume I need to change color scheme according to new design. I changed value of the variable $highlight_color to adjust it for new design in one part of some page but then I see that other parts of the page are broken. Moreover (and even worse) I don’t see many other pages which are broken too but I cannot evaluate number of such pages and parts of the application because all I see at the moment is name of the variable $highlight_color (instead of plain, self-explanatory and clear #123456 in one or two class definitions). Value of the variable is already changed so I don’t have an original (nothing to compare with) and I have to recollect which “relations” were present in the previous scheme and define new ones thereby multiplying future problems.
No matter how carefully were though over current constants definitions to represent current relations of colors, new design can easily beat them to pulp.
Yes there are obviously some momentary benefits but number of potential problems is even greater. The idea of “color relations” in itself seems very fragile for me.
If there are the same colors in several parts of application the same classes can be used in different contexts. Elaborate CSS will cope with most of your needs.
But once again it is just my point of view at the moment. Maybe I am completely wrong.
Alexei Gorkov on January 28th, 2007 at 1:16 pm
At the lowest layer, each element has a list of name value pairs (a property name and a literal). I’ve had to tear this stuff apart to make my css formatter: http://www.lonniebest.com/FormatCSS/
To allow constants, in the CSS itself, is to merge two distinct layers into one. Instead, I advocate building a javascript layer on top of CSS that allows you to dynamically build style sheets.
P.S.
Check out my Ajax Card Trick:
http://www.lonniebest.com/CardTrick/
Lonnie Best on February 5th, 2007 at 12:41 pm
Lonnie – I’m not a big fan of using JavaScript for styling purposes. My proposal doesn’t really change the name-value paradigm you speak of, it just adds new name-value pairs that can be used in place of literal CSS values.
Nicholas C. Zakas on February 5th, 2007 at 1:37 pm
You can try http://moonfall.org
Its a css processor that does variables, nested data structures that morph into css and even lets you define functions to handle dynamic resizing of stuff.
Sorry I don’t drink the cascading coolaid. It makes a coding mess in my opinion.
Kevin on September 20th, 2007 at 4:46 pm
Comments are automatically closed after 14 days.