The m is for maus~. I do what I please. About m~, The Archives and the Lifestream RSS

Progressive Enhancement: Radio Buttons

Each and every piece of content on the web should be available to anyone, no matter whether their browser capabilities, preferences, platform or security customizations. That’s what progressive enhancement stands for.

The Concept

I got the impulse of writing this pseudo-tutorial while answering a question on Forrst. Namely: “How to make custom radio button?“. Go read the question. I’ll wait.

Short disclaimer: I know of target audience, target browsers, javascript dependent interfaces and the likes. They’re besides the point of this article.

Progressive enhancement.

Sounds like big stuff, but the main proposition is this: each and every piece of content on the web should be available to anyone, no matter their browser capabilities, preferences, platform or security customizations. Just to make sure that my convoluted phrasing doesn’t make the concept of progressive enhancement sound more complex than it already did, I’m gonna rewrite it as a list of tasks.

  1. Write understandable copy (goes without saying).
  2. Use understandable, semantically correct, standards based markup to display the content. So far, every browser on the planet, using its default styling, would able to render the content in a usable fashion.
  3. Style the markup as you wish with CSS, keeping in mind that less capable browsers will perform differently to the new ones. To put it another way: your basic styling should do the significant work, while the more advanced part (like, say, CSS3 transformations), which might not be rendered at all, should only enhance the visitor’s experience (progressively, of course).
  4. Add behavior (like javascript or flash) only after making sure that your content is usable without it (i.e. the user can reach her goal even if javascript is disabled on her machine for security reasons). From this point on, do your worst. Catering for different processor powers is the only thing that’s left, and that’s absurd.

From the top: Content > Structure > Basic styling > Advanced styling > Behavior. Progressive, get it?

A Real World Example

Now let’s rephrase the original question. I’m gonna pretend it was written like this: How do you make sure that everyone can use the form, no matter the browser capabilities or the visitor’s disabilities? If you’re not the reading type, go ahead and check out the code example.


I’m gonna go ahead and create my own “real world example”. Sticking with single option questions, let’s ask about the visitor’s income, and divide it into 3 segments. In case you were wondering, I’m also asking myself why would anyone do that. But stick with me, I’m going places.

So, the task is “Choose your income level: small, medium, large.” We’re using big dollar signs in order to really get our point across.


First of all, we’ll mark it up just like regular radio inputs (using actual words for the choices, like “small”, “big”, etc.). There’s only 2 things we need to do in order to make sure that our enhanced version will work. First, we need to wrap the form controls in a container in order to be able to style that with a background image (the progress indicator). Second, the textual content of the labels needs to be wrapped in containers, also for styling purposes. What we get for each control is:

<label class='s'>
 <input type='radio' value='s' name='income_level'>

I’m not crazy about the spans, but whatcha gonna do? We’re gonna have to hide just the text while leaving the inputs alone.


Let’s style the labels (not the inputs) to display a background image instead of the texts. Then we’ll also add the horizontal progress indicator (so inappropriate) as a background image of the option group. The classic radio buttons are by now over the little bulges in the decoration. To see the CSS rules, just look at the source of the example.

We also add a few more rules for the enhanced version. What we want is:

  • to start with a background image that shows the preselected level;
  • to visibly hide the input boxes;
  • to have classes in place for various levels of income (different background position).

Now you’ve made sure that even people without javascript can use the form controls and we’ve prepared styles for the enhanced version.


We’re gonna add the behavior now and a bit more styling for those of us blessed with a better browser and great vision.

Using javascript, we add two classes to the option group, each for a specific purpose:

  1. One indicating that javascript is present (I used “live”, but it’s on no importance).
  2. The other we’ll use an indicator of the selected level in order to easily switch the background image by changing the container’s class.

We already have rules in place for the respective class that visibly hide the radio controls, and now they should come into effect. I emphasized the word “visibly” because we don’t want to have them removed from the document (by using display: none). Just out of sight. That way, when the label is clicked, the corresponding control will be selected. Plus, screen readers with javascript enabled won’t be left without the actual controls.

As soon as we add event listeners, we’re finished. Here’s what we’re trying to achieve: whenever someone clicks a certain point on the progress indicator or a label’s decoration, the background image of the inputs container is to be replaced by the appropriate one.

If you’ve somehow missed it, here’s the link for the code example again: ‘Progressive Enhancement: Radio Buttons’ Code Example.

Let’s wrap it up

Short revision: Content > Structure > Basic styling > Advanced styling > Behavior. The point of the article isn’t to be a tutorial on having custom radio buttons — although it serves that purpose too, to a degree — but to show how easy it actually is to make your content as accessible as it should be.

You just have to start from the lowest possible level of interactivity / features and build on that foundation, progressively adding features and/or levels of interaction.