Select Boxes with Style
by Castwide on 11-8-2007 Tags: code, css, javascript 15 commentsUpdate, 4-9-2008: The JavaScript code in this article has been modified to fix a problem with IE 6. The corrected code is available in both the article and the accompanying download. The changes are explained in more detail in this article.
I ran into a new obstacle in a recent Web 2.0 application. One of its forms contained a standard select box like the following:
Notice that the seventh option's caption gets clipped because it's longer than the width of the select box. My client wanted the options to use wrapping text, so the entire caption would always be visible despite the fixed width. I added a style ruleset for the option elements, and it worked in Firefox. Internet Explorer, however, ignored the new settings completely. A quick search of MSDN confirmed the problem:
Except for background-color and color, style settings applied through the style object for the option element are ignored [in Internet Explorer].
Lacking the option to use a standard select box, my only recourse was to create my own using a combination of CSS and JavaScript.
Fortunately, thanks to radio inputs and labels, plain HTML is capable of emulating much of the basic functionality of a select box. The HTML for the new select box is as follows:
<div class="selectbox" id="myselector">
<label>
<input type="radio" name="variable" value="1" />
One
</label>
<label>
<input type="radio" name="variable" value="2" />
Two
</label>
<label>
<input type="radio" name="variable" value="3" />
<strong>Three</strong>
</label>
<label>
<input type="radio" name="variable" value="4" />
Four
</label>
<label>
<input type="radio" name="variable" value="5" />
Five
</label>
<label>
<input type="radio" name="variable" value="6" />
Six
</label>
<label>
<input type="radio" name="variable" value="7" />
This is the seventh option in the list.
</label>
</div>
The emphasis on the third option is simply there to demonstrate the select box's embedded HTML capability.
I used the following style rules to make it look more like a typical select box:
.selectbox {
display: block;
width: 200px;
height: 90px;
margin: 4px;
padding: 0;
border: 2px inset #000000;
overflow: auto;
}
.selectbox label {
display: block;
border-bottom: 1px dotted #E0E0E0;
margin: 0;
padding: 0 2px 0 2px;
font-family: Arial;
}
Here is the result:
Because the radio inputs are wrapped in labels, they can be selected by clicking on the caption instead of the radio button itself. We're already more than halfway to the finish line.
One requirement remains. We need to hide all the radio inputs and highlight the captions when they get clicked. First, here's the additional style rule for selected labels:
.selectbox label.selected {
background-color: #000099;
color: #FFFFFF;
}
When the user selects an option, the label's class name should become "selected," while the labels of all unchecked options should be set to nothing. Now we need a bit of JavaScript to control the highlighting:
// This script requires Prototype (http://prototypejs.org)
var Selectbox = new function() {
var onClickInput = function(e) {
var inp = Event.element(e);
var box = inp.container;
highlight(box);
}
var highlight = function(box) {
var nodes = box.getElementsByTagName('input');
for (var i = 0; i < nodes.length; i++) {
if (nodes[i].checked) {
nodes[i].up('label').className = 'selected';
} else {
nodes[i].up('label').className = '';
}
}
}
this.enable = function(elem) {
var div = $(elem);
var labels = div.getElementsByTagName('label');
for (var i = 0; i < labels.length; i++) {
var l = $(labels[i]);
var inp;
if (l.htmlFor) {
inp = $(l.htmlFor);
} else {
inp = l.down('input');
}
if (inp) {
inp.label = l;
inp.container = div;
inp.style.display = 'none';
if (Prototype.Browser.IE) {
Event.observe(l, 'click', function(e) {
var lbl = Event.element(e);
var inp = (lbl.htmlFor ? $(lbl.htmlFor) : lbl.down('input'));
if (inp) {
inp.click();
}
});
}
Event.observe(inp, 'click', onClickInput);
}
}
highlight(div);
}
}
With the above script included in the page, we can add the last of the select box's functionality with one line of code:
Selectbox.enable('myselector');
...where 'myselector' is the ID of the select box's containing div.
Here is a complete demo:
If you need a select box that allows multiple selections, you can simply use checkbox inputs instead of radio inputs. The download at the end of this article includes an example.
This solution degrades gracefully into a standards-compliant set of radio inputs. Without the CSS and JavaScript, it still retains a minimum level of useability, including for form submissions.
Download the source and sample code (including the required Prototype library): http://dev.castwide.com/distro/selectbox.tar.gz
Comments
Max - 2008-01-30 09:55:36
Castwide - 2008-02-01 09:14:29
Ben - 2008-04-06 21:24:20
Castwide - 2008-04-09 01:29:22
Castwide - 2008-04-09 12:22:47
wowitsautumn - 2011-10-31 22:19:55
NORRTORIOUS - 2011-11-03 23:09:40
ScumWut - 2011-11-04 21:59:51
Mycarrox - 2011-11-17 21:29:37
jueodair - 2011-11-18 22:51:37
DeanMoriartyX - 2011-11-21 00:43:53
gothcrazybrit - 2011-11-21 19:39:23
edsonom - 2011-11-23 19:36:10
wibwobweb - 2011-11-25 08:15:53
kristaesson - 2011-11-28 22:46:55