Since the post on styling the input box I thought I’d post a another method to create custom drop-down lists. Again, most browsers won’t let you do very much in the way of styling. IE lets you mess with scrollbars and gecko and webkit let you adjust line-heights and padding, but really, you are STILL left with the default select. However, utilizing some html, css and JavaScript (through jQuery) we can have our own pretty nifty looking drop down. This is part of a UI suite I’m hoping to work on called Clair.
The functionality of our drop-down will mimic that of a regular dropdown box with one exception. Since we can not style the scrollbar, our drop-down will never display one. Instead, it will just keep expanding as you add new links.
HTML
To start off with, our select needs a few different elements to work properly. First off, we need a container that will hold our select. We will also require a list of elements that we want to appear when you click the drop-down. Finally, we need a default element to hold the current selected item and an arrow to signify that we can click on it to display more options. I’ve assigned the classes and Id’s to the elements as necessary. clair-select-active is the default item that will be displayed as well as what is displayed when an element is clicked on.
<div class="clair-select-container">
<div class="clair-select">
<div id="clair-select-active">Where My.Feet Have Been</div>
<ul class="clair-select-links">
<li><a href="#">Nookish</a></li>
<li><a href="#">Orange Pine Co</a></li>
<li><a href="#">Where My.Feet Have Been</a></li>
<li><a href="#">Your Website</a></li>
</ul>
</div>
</div>CSS
Before we get to the clair specific styles, these are the default ones applied to the entire page:
body{ font-family: Arial, sans-serif; font-weight: normal; font-size: 14pt; background-image: url('bg.png'); margin: 0px; } a { color: #CCC; font-weight: bold; text-decoration: none; }
The first style we get is the clair-select and the clair-select-container These style our entire select container.
.clair-select-container{ position: relative; padding: 10px 0px; margin: 0px 0px 40px; } .clair-select { background-color: #000; color: #CCC; -moz-border-radius: 12px; -webkit-border-radius: 12px; -o-border-radius: 12px; -khtml-border-radius: 12px; border-radius: 12px; padding: 10px 12px 5px; font-size: 14px; display: inline-block; border: solid #555; border-width: 1px 0px 0px 1px; width: 230px; -moz-box-sizing: border-box; box-sizing: border-box; opacity: 0.7; filter: alpha(opacity = 70); position: absolute; z-index: 2; }
The purpose of clair-select-container is to make sure when we expand our select dropdown it doesn’t push elements out of the way. Instead of floats nicely above them, and our slight opacity setting will display a faint outline of what it’s coverting.
There is a lot of vendor specific styling going on in clair-select, but the only one that I think warrants explanation is box-sizing and filter.
box-sizing: is a CSS3 spec that allows us to change the way that the browser interprets the “box-model” I’ll have to do another post to fully explain the box-model, but essentially it is the difference between including padding and border sizes within the “width” element, or adding it on afterwards. This forces Firefox to render the box-model the way Internet Explorer would 1.filter: is a Microsoft proprietary spec that allows us to use a number of IE only effects. The particular effect I am utilizing is alpha-blending which allows us to change the opacity of the element. I’ve turned the opacity done just a little so that things are still readable, while allowing us to see the background. This has the added benefit of a neat visual effect whereby it looks like our element is slightly inset.
The next style we’re going to add is that of the active element. All we do here is add the arrow as a background image and position it to appear on the right side of the element.
#clair-select-active{ background-image: url('down.png'); background-repeat: no-repeat; background-position: right; }
Finally, we’re going to style all the links. Nothing too fancy here. We’re just getting rid of bullets, spacing everything out a little and treating the anchor tags as block elements within our li’s.
.clair-select-links { margin: 0px; padding: 5px 0px 0px; display: none; } .clair-select-links li{ list-style: none; padding: 1px; margin: 0px; overflow: hidden; } .clair-select-links li a{ font-weight: normal; display: block; padding: 5px; margin: 0px; } .clair-select-links li a:hover{ background-color: #282828; -moz-border-radius: 8px; -webkit-border-radius: 8px; -o-border-radius: 8px; -khtml-border-radius: 8px; border-radius: 8px; color: #DDD; }
JavaScript
To add functionality to our drop-down we need a bit of JavaScript. I’m utilizing jQuery, but your own JavaScript library should have similar functions. We need to add two kinds of functionality.
- We need to switch between minimized and maximized states whenever a user clicks on the
clair-select-activeelement. - We need to switch to minimized and populate
clair-select-activewith the text from the menu item
$(document).ready(function(e) {
// This is just for cross-browser prettiness
$('#clair-select-active').css('cursor','pointer');
// This will toggle everything as necessary
$('#clair-select-active').click(function(e) {
if($('.clair-select-links').css('display') == 'block') {
$('.clair-select-links').slideUp();
}
else {
$('.clair-select-links').slideDown();
}
});
// This will populate clair-select-active with whatever you click on
$('.clair-select-links a').click(function(e) {
e.preventDefault();
$('#clair-select-active').html($(this).html());
$('.clair-select-links').slideUp();
});
});And that’s it, you’ve built a custom select drop-down. With a little JavaScript trickery, we can even go so far as to include it within forms. We’d just need a hidden form element and then when we populate clair-select-active we would also populate the value attribute of our form element.
This solution works in the following scenarios:
- IE 7+
- Firefox 3.5+
- Chrome 3+
- Opera 10+
You can download all the files used in this tutorial here: Custom Select Files
Notes:
- The IE way, takes your width and keeps your content that size, and adds borders and padding within it ↩

