It’s long been a problem for developers that the Select (or dropdown) input doesn’t allow you many options for customising their look and feel.
You shouldn’t be trying to style selects!
When you search for help on this matter, you often come across people arguing that select inputs get their style from whatever browser you are in and you should under no circumstance by trying to overrule browser behaviour.
That’s all well and good, but when a client asks for a website with a custom designed select, you can’t just say “You can’t have it”.
You’ve just got to get it done.
Plugins
There are already some great plugins out there, which take different approaches to solve this problem. My favourite is
My Solution
My aim is to have the look of the select styled completely outside of the original element, however it should still use the native select dropdown options when it is clicked.
Some plugins, including DropKick, hide the select and completely re-create the behavior using css and JavaScript. This is all very nice, and lets you have the most control over how the element and the options look, but it does present problems. The main issue is on touch devices like phones and tablets. These devices have their own way of handling dropdown behavior, which is usually quite nice and useable, while the functionality introduced by the JavaScript plugins is usually a little clunky and difficult to use.
Here’s my solution:
Use a jQuery selector to wrap the select in a div
$('select').wrap('<div class="style_select"></div>');
Add a span element into the div which will mimic the select text
$('.style_select').append('<span></span>');
Attach a change event to update the span caption whenever the select is updated
$('select').change(function(){ $(this).parent().find('span').html($(this).find('option:selected').text()); }); $('select').change();
Now for the css…
The aim is to hide the original select element, but still have it clickable. By setting the opacity to zero, and positioning the select absolutely above its holder it still receives the click event but is invisible until the dropdown is triggered.
.style_select{ position: relative; display: block; float:left; padding:17px; width:175px; margin-right:20px; overflow: hidden; background: url('../images/select-arrow.png') #f1f1f1 center right no-repeat; cursor: pointer; color: #3b4043; border:solid #e7e5e5 1px; } .style_select select{ -webkit-appearance: none; position: absolute; top:0; left:0; width:100%; height:48px; cursor:pointer; -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; filter: alpha(opacity=0); -moz-opacity: 0; -khtml-opacity: 0; opacity: 0; } .style_select span{ display: block; width:160px; height:1.14em; overflow: hidden; color: #888888; } .style_select select option{ padding:5px; border: none; }
I think this is a good compromise between getting your form element to fit in with the house styles while preserving the native browser behavior.
The only drawback is that you are still using the native dropdown which remains difficult to style, but the functionality is great on mobile devices and the other browsers all handle it as they see fit.