<Glazblog/>

CssHackz

I got this morning an interesting email. In substance, the fallback mechanism is not enough to Web Designers because there is for instance no way you can specify - in clean CSS w/o hacks - display: table-cell for browsers that support it and something else for those that don't support it w/o having major interactions between the two style sets... The question asked by the sender was "why can't we have something like the following ?"

if (display table-cell)
CSS stuff here
else
CSS stuff here
endif

My first reply was of course "nah, that not CSS's role to fix browsers' holes".

Thinking a bit more about it, I took it as a mental exercise:

  1. add some controls to CSS that can filter in/out based on the availability in the current rendering engine of a (property, value(s)) pair
  2. do that of course in a cross-browser JS chunk
  3. make sure that a stylesheet containing such a beast is still parsable from a CSS point of view

I took an hour to write it and I must say that even if this is probably not the kind of things one will ever use in a production environment, it's a funny exercise.

See the test document, the test "stylesheet" and the JS code. View the result here. Warning, it's a 0.1 I wrote in an hour. Still successfully tested on IE6, IE7, IE8, FF3, Safari 4 and Opera 9.

Comments

1. On Wednesday 4 March 2009, 15:37 by Olivier G.

Oh that would be awesome to be able to use that !

2. On Wednesday 4 March 2009, 16:04 by Rik

What about CSS Media Queries ?

3. On Wednesday 4 March 2009, 16:05 by Tim

Please, not _more_ JS libraries to include.

4. On Wednesday 4 March 2009, 16:08 by Daniel Glazman

@Tim: I agree. And as I said, this code will probably never be used in production contexts because stylesheet contents are downloaded twice and there is a potential"style flash" when the tests are resolved. So no worries. I took it only as a mental exercise.

5. On Thursday 5 March 2009, 07:30 by glandium

You could avoid downloading the stylesheet twice by using document.styleSheets and friends.

6. On Thursday 5 March 2009, 08:22 by Daniel Glazman

@glandium: no because what the CSS OM stores in the styleshet AFTER parsing so the unknown rules are thrown away and cannot be recovered, unfortunately...

7. On Thursday 5 March 2009, 09:39 by dakk

Its a good idea, and I stared doing something similar a couple days ago.

My overall project is much more complex, but one aspect is of it is server side dynamic css.

Right now, I have a table to store each css class joined together by a common stylesheet id, and I have a web service disguised as a css page serving out the stylesheets. I have some pretty good db caching plans so a stylesheet should be loaded only once per session per user, and then just served from memory after that, so I'm hoping it will be slightly faster than standard css, but it'll be close and users can each have a custom theme for every page of my site.

I've been struggling a lot to get some css hacks I shouldn't be trying to be stable. However, if I add an extra column for a browser flag to the classes it'll make my life so much easier. I can simply detect the browser from the request it sends, and use that to serve up rules custom for that browser.

I switching client side is going to be the best approach. It may be possible, but then you have two things to test on each browser, the css switcher and the css. Plus it means sending more data, and commandeering the client's cpu to do additional work. That's not a big issue on for standard visitors, but not something you'll want to do on smart phones. Lastly, if a browser has javascript disabled, they'll be stuck with what they get.

I've also heard of people using Apache and mod_rewrite to parse out the browser from the request and pick between css files to send back. I don't know how well this works or what it takes to implement, but I know web apps and dbs better than Apache hacks.

8. On Thursday 5 March 2009, 09:41 by dakk

I don't know what I did to the second to last line there. Should be:

I don't think switching css on the client side is the best approach.

9. On Thursday 5 March 2009, 12:06 by glandium

@dakk: only the client knows what it supports. The server can't know from the HTTP headers what CSS stanzas are supported. No, User-Agent is not a solution.

@glazou: I'm pretty sure to have seen something at least in a few browsers to allow to get the full css text. That's obviously and unfortunately not crossbrowser, though.

10. On Thursday 5 March 2009, 16:34 by gabriel

<anecdote>Three comments in the code, all of them concerning IE</anecdote>

11. On Tuesday 10 March 2009, 08:56 by Pierre

I would prefer a syntax like...

@if-implemented 'display: table-cell'
{
p { background-color: green; }
}

@if-not-implemented 'display: table-cell'
{
p { background-color: red; }
}