by Kyle Weems 2.March 2008 21:06
I tried really hard to start this post with a pop culture reference that somehow allegorically tied Alan Ruck’s relative anonymity despite his years of acting (including a major role in the pinnacle of 80’s teen films: Ferris Bueller’s Day Off) to the subject of toiling away at web design solutions on a daily basis. After reading what I just wrote, I realize that I may have too much spare time on my hands.
Fortunately for me, I spend at least a little of that time doing other things, like actually working on previously mentioned web design solutions. One area of interest that I’ve been getting more and more obsessed with is using Javascript to allow cross-browser CSS3 functionality on modern browsers, despite the fact that short of Konquerer, (which really annoys me because of the ‘cool’ spelling of a word with the letter K) browsers probably won’t be doing a lot of note with CSS3 until sometime after global warming causes the seas to rise and dolphins enslave humanity.
As much as I look forward to designing amazing tuna-oriented websites under the strict guidance of our future dolphin overlords, I’m not really interested in waiting any longer to get my hands on all the cool features of CSS3 that have been “on the horizon” for half a decade now. I’ve talked about this lack of patience before, discussing the ability to use CSS3’s multi-column features today with Cédric Savarese’s css3-multi-column.js (which I offered a slightly altered version of here) and adding some CSS3-like pseudo-class mimicking support with Alex Bischoff’s Offspring.js (introduce in a List Apart’s article Keeping Your Elements’ Kids in Line with Offspring, which I talk about here).
At some point, while I was sitting in Andy Clarke’s workshop at Web Directions North 2008 and dreamily drawing sketches of everyone’s favorite CSS rockstar, Andy talked about how it’s important to make use of cutting edge CSS features as often as possible to bring the browser makers’ attention to the fact that there is demand for support of these features. I think he was pushing in the right direction, but I think it’s not just enough to use modern browser support. I think people like Cédric and Alex are making strides in the right territory, which is using Javascript to implement CSS3 today.
Realizing it’d be a bunch of noise to just preach it without practicing, I’ve thrown my hat into the ring. My Javascript is a lot less practiced than my CSS, so I’m not exactly rocketing to the top with a killer script. However, they’re not nonexistent either, so I’ve put my nose to the grindstone.
The first challenge I decided to tackle was to fix an issue that I have with offspring.js. The script does a great (some might say overly thorough) job with adding classes to each element on the page so that they can be targeted with “pseudo-class”-like classes such as “.first-child”, “.last-child”, and “.nth-child” (it only currently supports the “odd”, “even”, and “#” values for nth-child). But to use these, you have to mark your CSS up with classes (such as “.last-child”) instead of pseudo-classes (such as “:last-child”). This is all great and dandy while modern browsers don’t have up-to-date CSS3 support. But as soon as they do (which, considering IE’s pace of advancement will be somewhere near 2020) you’d have to go through all your stylesheets and convert the styles to the proper pseudo-classes.
Not anymore. Let me introduce you to Pseudonut, a small script that goes through your stylesheets, checks for CSS3 pseudo-class selectors (currently only last-child, first-child, only-child, and nth-child) and then updates the stylesheets with new rules using classes instead. This means that you can drop the script into a project, use the supported CSS3 pseudo-classes, and it’ll convert them to a format for use with Offspring or any similar script you have.
Although it was my hope to use Javascript’s document.styleSheets.cssRules to read the existing selectors, strip out the pseudo-classes, and then replace them with classes, I ran into a major hurdle right away. Namely, most of the browsers wouldn’t actually read the pseudo-class marked selectors, as they’d see a style that held something they didn’t understand and therefore not add it to the list of cssRules. So instead I’m loading the stylesheets with XMLHttpRequest, splitting it into an array of strings holding the selectors and styles, making the changes from pseudo-class to class, then using javascript’s document.styleSheets.insertRule (or addRule if the viewer is using IE, since it has to be a special snowflake) to add the updated rule.
Here’s an example of it in work (I recommend checking out the stylesheets and html in Firebug). I’m using Offspring.js for adding the proper classes to the HTML, but you could use any script of your own for that feature.
Here’s the Javascript file: pseudonut.js.
Here’s the CSS file for that test: pseudonut.css.
Before I get reamed by Javascript experts for the cleanliness of the code (or lack thereof), I’d like to advise that this is what I’m calling version 0.1. It’s raw, it’s new, and it’s going to need a lot of polish. In particular I’m already thinking I should have loaded all the different pseudo-classes into an array of strings instead of checking for each separately. This is just the tip of the iceberg, though. Here’s a list of upgrades I plan for the project.
- Add configuration features so you can choose which pseudo-classes to support.
- Add support for all of CSS3’s pseudo-classes.
- Add the functionality to insert the needed classes into the HTML tags so that Pseudonut can stand alone without offspring (and ideally design it to only add extra classes to elements to tags that’ll need them, rather than Offspring’s jackhammer approach of banging them all), including full nth-child support.
- Add support for CSS3 attribute selectors.
Pseudonut is filling its initial purpose, which is to allow me to keep my stylesheets “clean” while still being able to make use of the features offered by Offspring and other such scripts. Going forward, I’m definitely open to suggestions or comments regarding whether such a thing is needed, and if so, what kind of changes or direction should occur.
Oh, and for those of you who are too young to have experienced Ferris Bueller’s Day Off, go watch it, if for no other reason than to be grateful that women don’t use as much hairspray today.