Cross browser
select boxes:

© Arie Molendijk: Crossbrowser Styling and Coding Select Boxes (having zero or no vertical size)

I. Styling the select box

1. Selected option (top option): text-color
In IE, we cannot style the text-color of the selected (top) option with internal or external sheets. We have to specify the color in the tag itself. But inline-styling does not work in non-IE. As a result, styling the color for the selected option (top option) must be done both inline and with sheets.

2. Selected option (top option): display
In non-IE, giving the selected (top) option 'display: none' will produce a nice effect: when the select box unfolds, the selected option will not 'show twice'. This doesn't work in IE and makes the text of the select box invisible in Opera (disaster!). So we use javascript to exclude IE and Opera:
<script type="text/javascript">
if(!window.opera && (/*@cc_on!@*/true)){document.write('<style style="text/css">.first_option{display:none}<\/style>')}
</script>
and give the selected option class="first_option".

3. Select and options: background
In all browsers except Chrome (and Safari?), the background for the options is inherited from the background given for the optgroups. In Chrome (and Safari?), the background for the options is inherited from the background given to the select tag. So even if we want the same background for the optgroups and the options, we have to style the select tag and the options separately.
IE and Opera do not allow us here to do the styling in the normal css-way, because a certain background given to the options will always be taken over by the select tag (in IE and Opera), even if the select is given its own background. We can get around the problem by specifying the background for the options via javascript. This will allow us to do the option's backgrounding for all browsers except IE and Opera. (In IE and Opera, the options will get their background via the optgroup, see above). We could do something like:
<script type="text/javascript">
if(!window.opera && (/*@cc_on!@*/true)){document.write('<style style="text/css">option{background: black}<\/style>')}
</script>
Combining this script with the one given in 2 above yields:
<script type="text/javascript">
if(!window.opera && (/*@cc_on!@*/true)){
document.write('<style style="text/css">.first_option{display:none}');
document.write('option{background: black}');
document.write('<\/style>');
}
</script>

4. Options and optgroup: font size
Styling the font-size of the options and the optgroups cannot be done in IE with style sheets, nor with inline styles.

5. Select box and options: width
In IE, the options inherit their width from the width given for the select tag. So they may end up to be too narrow (or, if the width fits the size of the options, the select box itself may be too wide). Part of the problem can be resolved by doing the the following:
<select name="something" id="something" style="position:relative;width:90px;" onchange="selectedIndex=0;this.style.width='90px'" onblur="this.style.width='90px'" onmousedown="this.style.width='220px'">
If the length of the widest option equals 220px, and if the width of the select box (= of the selection (top) option) equals 90px (just an example), the select box will not be too wide when the options are not unfolded. And the options will have the desired width when we click on the box. But there is a problem: when we click on the select box, the selected option (the select box itself) will be wider than 90px: its length will equal 220px, which is too big.
We can easily resolve the problem for non-IE. We make sure that the dynamic sizing of the select box does not apply to non-IE:
<select name="something" id="something" style="position:relative;width:90px;" onchange="selectedIndex=0;if (/*@cc_on!@*/false){this.style.width='90px'};" onblur="if (/*@cc_on!@*/false){this.style.width='90px'}" onmousedown="if (/*@cc_on!@*/false){this.style.width='220px'}" >
But how about IE? The solution is to wrap the select box in a div tag having 'overflow: hidden' and a width that is a couple of pixels bigger than the width given to the select tag. In our case, this will produce something like:
<!--[if IE]> <div style="width:93px;overflow:hidden;"> <![endif]-->
<select name="something" id="something" style="position:relative;width:90px;" onchange="selectedIndex=0;if (/*@cc_on!@*/false){this.style.width='90px'};" onblur="if (/*@cc_on!@*/false){this.style.width='90px'}" onmousedown="if (/*@cc_on!@*/false){this.style.width='220px'}" >
options ...
</select>
</div>
Although the div is not needed for non-IE, we don't need to specify this on our page, since the div won't hurt non-IE. But if we want a div for IE that looks different from the div for non-IE - we may want a black div-border for IE but not for non-IE, for instance, because that makes IE look better - we can do something like this:
<!--[if IE]> <div style="width:93px; overflow:hidden; border: 1px solid black"> <![endif]-->
<!--[if !IE]><!--> <div> <!--<![endif]-->
<select name="something" id="something" style="position:relative;width:90px;" onchange="selectedIndex=0;if (/*@cc_on!@*/false){this.style.width='90px'};" onblur="if (/*@cc_on!@*/false){this.style.width='90px'}" onmousedown="if (/*@cc_on!@*/false){this.style.width='220px'}" >
options ...
</select>
</div>
6. Focus on an option in IE and blue background
If we click on an option of a select box in IE, the top (selected) option (= the unfolded select box) turns into blue. If we don't want that, just add this.blur to the 'onchange'. It works for IE, and doesn't hurt non-IE.

7. Closing a select box when another select box receives focus
In IE and Chrome (plus Safari?), an unfolded select box looses focus as soon as another box gets focus. The nice thing about this is that we only need one click when we want to close an unfolded select box and, at the same time, unfold another one. (We don't need an 'extra' click). Unfortunately, this does not work in non-IE (except Chrome). The workaround is to add onmousemove="this.focus()" to the select tag. This will close an unfolded box as soon as the mouse goes over another one. We should reserve the onmousemove to non-IE (doesn't hurt Chrome), because in IE, it will make the select box turn into blue; the blue color only disappears when we click somewhere on the screen. So: onmousemove="if (/*@cc_on!@*/true){this.focus()}"

8. Cursor: pointer
In all browsers except IE, we can give a 'hand' to the select box: select {cursor: pointer}.


II. Coding the select box

Here's what we've got so far:
<!--[if IE]> <div style="width:93px; overflow:hidden; border: 1px solid black"> <![endif]-->
<!--[if !IE]><!--> <div> <!--<![endif]-->
<select name="something" id="something" style="position:relative;width:90px;" onchange="selectedIndex=0;this.blur();if (/*@cc_on!@*/false){this.style.width='90px'};" onblur="if (/*@cc_on!@*/false){this.style.width='90px'}" onmousedown="if (/*@cc_on!@*/false){this.style.width='220px'}" onmousemove="if (/*@cc_on!@*/true){this.focus()}" >
options ...
</select>
</div>
In non-IE, it's possible to make function calls in the options. We could do, for instance: <option value="" onclick="document.body.style.background='blue'">Make blue background</option>. But this is not possible in IE. Fortunately, there's a way to make it work both in non-IE and IE, with the help of the following script. The functions are just examples. we can add as many else ifs as we like, and remove the ones we don't need (but leave if (optionValue=="none") {} and else {location.href=optionValue} intact):
<script type="text/javascript">
function coding_box(which_box) {
var optionValue = document.getElementById(which_box).options[document.getElementById(which_box).selectedIndex].value;
if (optionValue=="none") {}
else if(optionValue=="blue"){document.body.style.background='blue'}
else if(optionValue=="white"){document.body.style.background='white'}
else if(optionValue=="meaning"){alert('Get yourself a private guru!')}
else if (optionValue=="popup") {window.open('http://www.google.com','','toolbar=1, location=1, directories=1, status=1, menubar=1, scrollbars=1, resizable=1, width=600px, height=350px, top=50px, left=100px');}
else if(optionValue=="hide1"){document.getElementById('box1').style.display='none'}
else if(optionValue=="show1"){document.getElementById('box1').style.display='inline'}
else if(optionValue=="hide2"){document.getElementById('box2').style.display='none'}
else if(optionValue=="show2"){document.getElementById('box2').style.display='inline'}
/*else if ADD MORE FUNCTIONS HERE */
else {location.href=optionValue}
}
</script>
Using the script in a select box implies that we must have onchange="coding_box('something') in it, where 'something' is the ID of the select tag. In the following:
<!--[if IE]> <div style="width:93px; overflow:hidden; border: 1px solid black"> <![endif]-->
<!--[if !IE]><!--> <div> <!--<![endif]-->
<select name="something" id="something" style="position:relative;width:90px;" onchange="coding_box('something');selectedIndex=0;this.blur();if (/*@cc_on!@*/false){this.style.width='90px'};" onblur="if (/*@cc_on!@*/false){this.style.width='90px'}" onmousedown="if (/*@cc_on!@*/false){this.style.width='220px'}" onmousemove="if (/*@cc_on!@*/true){this.focus()}" >
<option value="none" selected style="color:darkred" class="first_option" >Select 1</option>
<option value="blue" >Create blue background</option>
<option value="white" >Create white background</option>
<option value="meaning" >Click to see meaning of life</option>
<option value="popup">Google in new window</option>
<option value="hide2" >Hide second box</option>
<option value="show2" >Show second box</option>
<option value="http://www.google.com">Google in this window</option>
</select>
</div>
a click on the option having value="blue" would cause the background of the page to turn into blue, because in our script we have 'else if(optionValue=="blue"){document.body.style.background='blue'}. If we also had a select box similar to the one above but with name="box2" id="box2", a click on the option having value="hide2" (of this box) would hide the other box, because in our script we have 'else if(optionValue=="hide2"){document.getElementById('box2').style.display='none'}, and a click on the option having value="show2" would make the other box visible again, because in our script we have 'else if(optionValue=="show2"){document.getElementById('box2').style.display='inline'}, etc.


III. Styling and coding the select box: final remarks

We've seen that select boxes can be styled to a limited extend, and that there's a crossbrowser way to (i) specify their width; (ii) make function calls in select boxes.
The two boxes to the left serve as demonstrations of what has been explained above. Try them.

Note:
We need this to keep the main option selected in IE after going to another page and then returning to this one:
<script type="text/javascript">
/* Needed to keep 'selected' intact. */
function selected(){
for (i=0;i<document.getElementsByTagName('select').length; i++) {
document.getElementsByTagName('select').item(i).selectedIndex=0;
}
}
document.onmouseover=selected;
</script>