Better Looking Select Elements that Look the Same in All Browsers via CSS

Select elements (often called dropdowns) suck. They just look weird, especially when you start styling your regular inputs, you might end up getting something that looks like this in a form:

screenshot of default select styling on Mac / Chrome

Not the worst, but look at what happens when you start pairing them up with other input elements which we have styled:

default select element styling doesn't match up with inputs, and then causes labels and other things to get wacky

I wouldn’t ask my mother’s worst enemy to marry that atrocity, even if it could cook a turkey with one hand while waking up the whole neighborhood with a merry-go-round-the-block in the other.

So what can we do about it?

CSS, thank Zeus!

Here’s the bare minimum you’ll need, and this will give you support for Chrome, Firefox, Safari and IE 10, 11 & Edge (IE9 support outlined below, along with iOS support).

Firstly, all select elements need to be wrapped in a containing element. Them’s just the shakes, kid, you see, :pseudo elements can’t be applied to select elements. So deal with it. For the purposes of this post, let’s say you’re wrapping them all in a <div class="select-container"> element.

select {
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
padding: .5em;
background: #efefef;
border: none;
border-radius: 3px;
padding: 1em 2em 1em 1em;
font-size: 1em;
}
.select-container {position:relative; display: inline;}
.select-container:after {content:""; width:0; height:0; position:absolute; pointer-events: none;}
.select-container:after {
border-left: 5px solid transparent;
border-right: 5px solid transparent;
top: .3em;
right: .75em;
border-top: 8px solid black;
opacity: 0.5;
}
select::-ms-expand {
display: none;
}

There you have it!

Note that last bit is for more modern versions of Internet Explorer.

Now you’ll see this in Chrome:

perfection in Chrome!
Chrome as of Version 50.0.2661.102 (64-bit)

Want more screenshots?

good to go in Safari
Safari 9.0.2 is just about identical.
A+ in FF
Firefox 40.0.2 is on board.
Microsoft finally took the edge off...blarney stone funny there folks!
Edge on Windows 10 looks great.
Internet Explorer 11 looks good
IE11 gets the job done.
Internet Explorer 10 looks accurate
IE10, too.

As far as I’m concerned, that’s “all major browsers”, on desktop anyway.

iOS Support

Here’s what it looks like on iPhone:

iPhone renders short select fields with wrapped text
I don’t know…not great.

I don’t think we want that, though. On one hand, you could just not make your selects as small as I have that one, which is completely doable, and it does allow the user to somewhat read the first choice. But if we add this:

select {
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
}

Then we get this on mobile:

looking better on iOS
That’s not ideal, either, but it’s more of what the default behavior is in browsers anyway.

What about IE9?

Finally, if you want to support IE9, you can do the whole conditional stylesheet thing. Add this to your site or page’s head tags:

<!--[if IE 9]>
<link rel="stylesheet" type="text/css" href="ie9fix.css">
<![endif]-->

And then put this into that file:

.select-container:before {position:absolute; right:.25em; top:-.2em; width:2.5em; height:1.75em; background:#efefef; content:""; z-index:7;}
.select-container:after {z-index:9;}

That’ll fix IE9 up for you like so, by adding a second pseudo element to cover up the default dropdown arrow (which is still there, just covered up now):

Internet Explorer 9 is now on board.

No support for IE8 or below, I guess, though I didn’t really even try given the fact that the future was the year 2000 and we’re half a nation away from a Trump presidency. Figure I should probably go enjoy life while we still can.

Up Next: Simple WordPress Breadcrumbs, Including JSON Examples!