An accessible, keyboard friendly custom select menu

I’ve always been wary of styling form elements too much. Possible usability and accessibility issues, browser quirks, and the fact that the CSS specification does not define form control styling are the main reasons.

With that said, sometimes you have to do things you don’t really want to. Like styling select elements, which I’ve recently had to find a way to do. There are quite a few workarounds for doing this out there. However, most of the ones I looked at replace the select element with a bunch of links which changes semantics and behaviour a bit too much for my tastes. I couldn’t find any implementation that I was completely happy with, so I took the best one I could find and tweaked it.

In my book, a custom select element should:

The safest way to do this is to only style the closed select element and leave styling of the opened state to the browser, which is what Alen Grakalic does in Custom styling of the SELECT elements. So I decided to use that as a starting point and add some refinements to make it work the way I want it to.

The clever trick Alen uses is to make the real select element completely transparent and place it on top of a span element that you can style exactly the way you want to. When the select menu is opened, the options are displayed the way the browser normally displays them. No, the options aren’t custom styled, but in most cases it’s the appearance of the closed select element that is most important to the design. YMMV.

Some of the changes I’ve made are these:

The entire script (which is written as a jQuery plugin) is available in jquery.customselect.js. You can find some examples of the script in action on the Accessible, keyboard friendly custom select menu demo page.

Of course the custom select element needs a bit of CSS as well. It isn’t particularly complicated, so please view source on the demo page for a closer look.

To make the fake select flexible (both horizontally and vertically), I’ve used a background image that is both taller and wider than I expect a select to become. In this case it’s just a gradient with a separator and an arrow, so you could likely do the whole thing with CSS3 and avoid using any images at all if you wanted to.

As for browser support, I have tested this without noticing any issues in IE7+ and the latest versions of Firefox, Safari (OS X and iOS), Chrome and Opera. In IE7 and IE8 the fake select doesn’t get rounded corners or drop shadows, but it’s possible to work around that by using CSS3 PIE. Or you could just live with different rendering in those browsers. If you really, really have to you could probably make this work in IE6 as well, though I decided to stop at IE7.

With JavaScript off, the custom select element becomes a standard select element rendered with each browser’s default styling.

And finally a reminder: Just because you can, doesn’t mean you should.

Posted on November 3, 2011 in Accessibility, JavaScript, CSS