Exploration

A while back, I woke up one morning thinking, John Resig’s got some great CSS3 support in jQuery but it’s all forced into JS statements. I should ask him if he could set things up like Dean Edwards‘ IE7 script so that the JS scans the author’s CSS, finds the advanced selectors, does any necessary backend juggling, and makes CSS3 selector support Transparently Just Work. And then he could put that back into jQuery.

And then, after breakfast, I fired up my feed reader and saw Simon Willison‘s link to John Resig’s nascent Sizzle project.

I swear to Ged this is how it happened.

Personally, I can’t wait for Sizzle to be finished, because I’m absolutely going to use it and recommend its use far and wide. As far as I’m concerned, though, it’s a first step into a larger world.

Think about it: most of the browser development work these days seems to be going into JavaScript performance. Those engines are being overhauled and souped up and tuned and re-tuned to the point that performance is improving by orders of magnitude. Scanning the DOM tree and doing things to it, which used to be slow and difficult, is becoming lightning-fast and easy.

So why not write JS to implement multiple background-image support in all browsers? All that’s needed is to scan the CSS, find instances of multiple-image backgrounds, and then dynamically add divs, one per extra background image, to get the intended effect.

Just like that, you’ve used the browser’s JS to extend its CSS support. This approach advances standards support in browsers from the ground up, instead of waiting for the browser teams to do it for us.

I suspect that not quite everything in CSS3 will be amenable to this approach, but you might be surprised. Seems to me that you could do background sizing with some div-and-positioning tricks, and text-shadow could be supportable using a sIFR-like technique, though line breaks would be a bear to handle. RGBa and HSLa colors could be simulated with creative element reworking and opacity, and HSL itself could be (mostly?) supported in IE with HSL-to-RGB calculations. And so on.

There are two primary benefits here. The first is obvious: we can stop waiting around for browser makers to give us what we want, thanks to their efforts on JS engines, and start using the advanced CSS we’ve been hearing about for years. The second is that the process of finding out which parts of the spec work in the real world, and which fall down, will be greatly accelerated. If it turns out nobody uses (say) background-clip, even given its availability via a CSS/JS library, then that’s worth knowing.

What I wonder is whether the W3C could be convinced that two JavaScript libraries supporting a given CSS module would constitute “interoperable implementations”, and thus allow the specification to move forward on the process track. Or heck, what about considering a single library getting consistent support in two or more browsers as interoperable? There’s a chance here to jump-start the entire process, front to back.

It is true that browsers without JavaScript will not get the advanced CSS effects, but older browsers don’t get our current CSS, and we use it anyway. (Still older browsers don’t understand any CSS at all.) It’s the same problem we’ve always faced, and everyone will face it differently.

We don’t have to restrict this to CSS, either. As I showed with my href-anywhere demo, it’s possible to extend markup using JS. (No, not without breaking validation: you’d need a custom DTD for that. Hmmm.) So it would be possible to use JS to, say, add audio and video support to currently-available browsers, and even older browsers. All you’d have to do is convert the HTML5 element into HTML4 elements, dynamically writing out the needed attributes and so forth. It might not be a perfect 1:1 translation, but it would likely be serviceable—and would tear down some of the highest barriers to adoption.

There’s more to consider, as well: the ability to create our very own “standards”. Maybe you’ve always wanted a text-shake property, which jiggles the letters up and down randomly to look like the element got shaken up a bit. Call it -myCSS-text-shake or something else with a proper “vendor” prefix—we’re all vendors now, baby!—and go to town. Who knows? If a property or markup element or attribute suddenly takes off like wildfire, it might well make it into a specification. After all, the HTML 5 Working Group is now explicitly set up to prefer things which are implemented over things that are not. Perhaps the CSS Working Group would move in a similar direction, given a world where we were all experimenting with our own ideas and seeing the best ideas gain widespread adoption.

In the end, as I said in Chicago last week, the triumph of standards (specifically, the DOM standard) will permit us to push standards support forward now, and save some standards that are currently dying on the vine. All we have to do now is start pushing. Sizzle is a start. Who will take the next step, and the step after that?

Justin wrote in to say...

Mozilla, at least, does not make unrecognized CSS rules or properties accessible from JavaScript. IE does, which is why Dean Edward’s IE7 works. I’m not sure what other browsers do. One would have to write code to retrieve the raw stylesheet and parse it manually to see “new” selectors and properties.

On a few projects I have sent an IE6 jQuery file to add a .hover or .submit class to replace things that don’t work on IE such as :hover or input[type=submit]. Something like this would be really handy as it would save my time and let me get on with important parts.

mike wrote in to say...

At last! I’d been kicking around the idea of mimicking support of certain CSS3 abilities with JavaScript, but now I can be lazy and enjoy the fruits of a smarter, harder-working person’s labor. Sweet!

@Justin – You may not be able to access CSS styles in Mozilla with JS via the normal stylesheet-related functions, but you can access the sheets via a technique like Ajax and then parsing the text inside. It’s not exactly as quick, mind you, but I did something when creating a script that would convert CSS3 pseudoclasses into classes for browsers that didn’t support the CSS3 selectors.

Wow, Sizzle is EXACTLY the answer to a post I wrote a while back, about why CSS _must_ borrow more from programming languages to succeed in future. And here it is, a solution which incorporates a lot of the stuff I was talking about and which gives a middle finger to the W3C’s rational of “but CSS shouldn’t allow complex logic, and designers don’t want it anyway” (Bert Bos…)

Marching to our own standards, as you know, is something I’ve been pounding the table for for more than four years now. Everyone is capable of creating a benevolent new standard. What determines whether it is a “real” standard is not determined by who creates it, but rather who endorses and uses it.

Widespread use = standard.

One of the nicest examples I’ve seen of something along the lines of what you mention above is The Wolf’s <a href=”Absolute Clearance. The ability to clear absolutely positioned columns as if they were floats, using javascript… brilliant and ever so useful.

Why is it that you contend that JavaScript is lightening fast at traversing these elements?

Even with the new versions of jQuery, on IE6 and IE7, doing DOM traversal and manipulation still seems to slow down the page loading quite a bit.

Lately, I have been able to optimize my page load times simply by replacing the DOM manipulation and traversal done in my JavaScript initialization functions with upfront rendering by CSS and my server-side templating language.

It makes me tentative to go down the road of using JavaScript to replace CSS’ inadequacies.

@Kyle Using AJAX to retrieve raw CSS is going to conflict with cross-site scripting restrictions. i.e. can you access CSS from other domains? Are you following YSlow’s recommendations to put all static content (CSS) on a CDN (another domain?)

Also, how do you spot the difference between a rule the browser doesn’t understand, and one it does – without coding knowledge in for every browser? Does mutiple background-image support suddenly mean that element.style.backgroundImage is an array instead of a string? In all browsers?

So at the Ajax Experience John Resig spoke a little bit about Sizzle but I don’t recall him saying anything about parsing CSS rules from files, etc. He seemed to be describing it as a standalone selector engine ala CSSQuery, only it could be plugged into jQuery and Prototype etc. etc. etc. But the specifying selector work would still have to be JS driven.

I’d be delighted, don’t get me wrong.

We will see. Either way, I still enjoy being able to specify advanced selectors in jQuery and have IE6 etc. apply a class that I know one day can GO AWAY.

Sean Hogan wrote in to say...

There would be lots of restrictions on this solution:
– Until we get CS-XHR the JS library can only read same-domain CSS files.
– If the CSS-upgrade-in-JS adds elements to the DOM then other DOM manipulation code needs to work around it.

I don’t agree with what your suggesting here because your essentially suggesting that people should go out and write their own CSS rendering engines.

This is theory sounds fine; however, Web Developers/Designers currently have to battle with the differences in Real browser rendering engines and now we’ll have to take into consideration JavaScript rendering engines… if we choose to use them.

@Ash – Granted, that adds an extra wrinkle when the stylesheets are on another domain. But cross-site Ajax scripting solutions exist, so that’s something that can be worked around if need be. Since Resig is way more talented than I am at this, I’m suspecting he’s going to use a better solution to the “accessing rules that Mozilla ignores” problem that Justin mentioned.

Ivan wrote in to say...

Yeah I don’t think sizzle works that way, but it might be nice. A problem with js-based resolution of selectors is also that the dom might be updated via ajax, and then after the selectors would need to be re-applied. To make that transparent to the developer seems reaaaaly tricky.

Sizzle is definitly a standalone DOM-Selection engine. If you would want one of those who seems to be working right now, I consider Peppy a nice and really fast one. But both are not designed for reading css.

But still, I consider this idea of yours, eric, as a really good one. One that is worth to be followed. If someone finds a way to make this happen and working fast, it really could push forward the way we designer could use the browsers and design websites for it.

And web standards just fly right out the window. I can see Bert Bos shaking his head over this hybrid JS / CSS language that you and others are proposing. Will you stop pandering to the interest of MS and their antiquated bundled software called IE. Break the web now.

Erik wrote in to say...

With all the work being done to add variables/constants and expressions to CSS, and the widespread use of JS libraries to enhance websites, it feels more and more like the two should merge.

Make CSS part of javascript so that I can interact with it without loading a large JS library.

Further, imagine if HTML didn’t have a fixed set of tags, then you could have all the semantics you wanted – and you wouldn’t need all those IDs and classes littering your markup just to style or add functionality to your site!

Call me a purist, but it seems that this approach, while novel, is more of an academic exercise and a bold hack, not a solution (note: I realize that this opinion will probably get me flamed :/). Using javscript to add additional markup in order to “simulate” multiple bg images is just _asking_ for headaches, IMO. I know that’s an extreme example, but let’s not get to thinking that javascript will save the browsers and alleviate all our problems.

What Eric suggested initially is a great idea: use your CSS3-compliant javascript library of choice to apply CSS3-compliant style rules to elements that the browser’s rendering engine has politely ignored. We already do this with all those wacky (and insanely helpful) CSS2 selectors, so why not keep building?

Eric,
Javascript to the rescue on another front, as well:ZoomPerfect is the name of the product and it quite elegantly solves a problem that has been, for years, presumed to be unsolvable.
It uses javascript to turn Internet Explorer’s Text Size menu into a true Text Zoom and/or Style-Switcher; enabling IE to size and resize text set in pixels; detect and modify Zoom levels; and a lot more.
Works transparently, quite amazing.
It’s in “preview” at the moment awaiting a more solid Beta of IE8.
All invited to stop by, check it out, and sign up for updates until the final release.

The important thing should still be (X)HTML and CSS progressivly enhanced through js. What you and others are propagating, is a new web build only on javascript.

I don’t read this suggestion as a web that is built only on JavaScript at all. It is still progressive enhancement and not built solely on JavaScript. This is a means to get extensions as a temporary solution for shortcomings in CSS3 implementations in browsers. Eric says so himself when he talks about using the JS to extend CSS and markup. Extend means it would already work on its own, but it would work better when JS is enabled.

That is progressive enhancement — maybe not as first envisioned, but it still builds on that solid platform.

@Eric: I’m very much interested in this idea; we’re using it in a number of ways already to extend and enhance the accessibility and usability of the web — we’re fixing behaviours, bugs and other problems with the way things work by using JavaScript. It seems perfectly logical to me to explore what you’re suggesting, provided that there is a solid foundation of HTML, CSS and JS upon which we would build.

I had a very similar idea to this, but it went a little further.. along with supporting CSS3 by dissecting the stylesheets, wouldn’t it be cool to have the framework read and render XML and XML styles and if the browser was one that didn’t natively support XML styles, it would then replace the xml with a div with a class that was equivelent? Check it out..
<xml>
<error>Your page had an error</error>
</xml>

This would sure make life a lot easier. The only browser that currently supports css selectors like #my_id input[type=radio]:checked + label correctly is FireFox 2+ as far as I know. I use it in one of my recent projects, iStylr – CSS Template Generator anyhow and therefore limit access to FireFox users only (not the best way – I know)

[…] our browsers, and possibly more than anything — our JavaScript libraries. A recent post over at MeyerWeb points to the fact that Javascript has not only matured, but is pushing the future of browsing. […]

The idea of using js to fix browser CSS has been implemented in Andy Kent’s JSS and I have a CSS parser/jQuery-plugin adapter (to do things like div { -jquery-shakeUp: fast 5px } in the stylesheets. The documentation still needs work, but the code works nicely in all the major browsers. Demo here.

[…] that the browser cannot handle, and uses jQuery to implement them. Eric Meyer recently had a similar idea. $.cssparser.isValidSelector takes a string and returns true if the browser recognizes it as a CSS […]

Brilliant Eric. As more and more modern browsers support CSS3 we use javascript to fix the old non-compliant ones. If it’s a bit slower on ie6 so be it – it’s time to move on. This is the ultimate in progressive enhancement. I also support the idea of creating our own sellectors, we are the ones building the web, so we should be the ones helping to design the architecture as well – from the ground up.

[…] I say we get over it CSS 3 just isn’t happening any time soon, the css working group has failed us, and for the near future maybe Eric Meyer might have more than he thought with his post on javascript as our saviour. […]

[…] JavaScript Will Save Us All Eric Meyer’s opinion on why we should look to JavaScript to extended standard support badly lacking in many browsers, instead of waiting for the browser vendors to implement them. […]

[…] practicality to become a deeply philosophical choice. It is by default accessible, semantic, and extensible. Visitors to the site can print the content, copy it, re-size it, steal it, and manipulate it with […]

Mason Fischer wrote in to say...

[…] Transcending CSS, recommending Dean Edwards‘ ie7-js scripts. Eric Meyer has also written that JavaScript Will Save Us All to “use the browser’s JS to extend its CSS support”. I still think that this is an option […]

Remember to encode character entities if you're posting markup examples! Management reserves the right to edit or remove any comment—especially those that are abusive, irrelevant to the topic at hand, or made by anonymous posters—although honestly, most edits are a matter of fixing mangled markup. Thus the note about encoding your entities. If you're satisfied with what you've written, then go ahead...