I have to thank a lot of people I asked in the research for this, foremost James Edwards, John Resig and Andrew Dupont. I’ve also given a short presentation – PDF -96KB on the same topic at the Barcamp in London last weekend.
First of all let’s investigate how pure CSS solutions became so popular.
In the days before the CSS revolution
These could be a simple rollover effects over images and text that indicate that these elements are clickable right up to clever forms that show and hide fields that are logically connected (for example showing a second address field set when you select more than one applicant for a mortgage).
lead to convoluted code that made maintenance a nightmare as you had to change things in several places whenever there was an amendment to be made.
It just felt wrong that you had to learn a different language and know how to avoid mistakes implementing it just to achieve simple effects. Furthermore it is a pain to re-visit these implementations whenever a new browser showed up and the earlier script didn’t take that into account but tested only for certain browsers.
CSS superheroes to the rescue
CSS - the one trick pony
The part of CSS that makes effects like these possible is pseudo classes. These define styles applied to an element when something happens to it. For example you hover over it with the mouse cursor, or you set the focus to it with your keyboard. The snag is that browser support right now is still flaky, especially in MSIE 6 which only allows for hover effects on links. This does actually make sense, as they are (apart from buttons) the only clickable elements in browsers. A hover effect was originally meant to be an indicator that what you are pointing your mouse at is in fact leading to someplace else or triggers a certain functionality.
A problem of scope
Regardless of the level of support for pseudo selectors, the biggest problem of CSS-only solutions is scope. You can only affect elements that are nested inside the element you define the hover style for. This, together with MSIE 6’s support issues limits you to inline elements for your CSS-only effects, unless you choose to create invalid HTML. Furthermore pseudo selectors don’t add to the specificity of a CSS selector, which can make it very tricky to define different styles.
A problem of accessibility, semantics and content
The necessity to nest all the elements affected by the hover styling also brings up the issue of altering the HTML and content to cater for an effect. While it is rather cool to see a link called “Products” and a styled tool tip saying “Check our range of toys, books and apparel for men and women” when you hover over it, it may be less fun having to listen to “Products Check our range of toys books and apparel for men an women” or see it when you don’t have CSS enabled or available. After all, you only wanted to know which link leads to the product page.
Assistive technology like screen readers allows you to quickly navigate through the document with a listing of all the links in the document. If all your links are that long – or even worse encompass whole paragraphs of text – this very useful feature becomes a pain to use.
Summary of CSS-only solutions:
In essence, CSS-only solutions were a good exercise to push the limits of CSS and advertise the necessity for browsers to support the W3C recommendations. However, for real “behavioural” solutions, CSS is simply not the correct technology:
- You cannot test properly with CSS – there is no conditional syntax, instead you need to rely on browsers and visitors being able to understand and use your solution or get an unusable page.
- You are at the mercy of the browser when it comes to keyboard support. While the focus pseudo class offers you the option to trigger a style application via keyboard, browsers only allow keyboard access to links and buttons. You also only allow for keyboard support for web pages, not for applications (more on that later).
- With links being inline elements you can only nest other inline elements in them, and you may make it a real pain for users relying on assistive technology to use your site.
- CSS behaviour is a fixed state – either you are hovering over the element and you show the nested one or you are not. There is no way to allow the user to make a mistake or move the mouse slightly without losing the extra information or – in worse cases – collapse a whole menu.
Notice that we are talking about modern DOM scripting here, that works unobtrusively and follows the idea of progressive enhancement. It is easy to find examples of scripts that don’t help the cause, so please let the sins of the past be behind us.
Real progressive enhancement
Reading and testing environments
Removal and generation of elements
Time based execution
Richer event handling
Real keyboard support
This enables you to create menus that work like real application menus. While the normal “web way” of navigating through a list of links via keyboard is to jump from link to link via Tab (or the “A” key in Opera), real application menus like the Windows start bar or any dropdown in the browser menu can be navigated with the arrow keys.
Newer versions of Opera and modified versions of Firefox also allow for this kind of navigation and Sun has cooperated with Mozilla to come up with a reusable library of DHTML widgets that follow these rules. James Edwards also created a DHTML menu that works the same way.
On demand pulling of content
The big question
In summary, there is one big question you should ask yourself: what is a better solution:
- A solution that doesn’t even show up for the visitor when something is turned off or
- a solution that may not be usable without you being able to do anything about it as the technology it was built on was never meant to be used for application development.