Problem

Style <select> to look better, osm! and not like native select on given OS, basically convert this:

into this:

requirements

Solution

You can find many different approaches over the Internet how to achieve this, but most of them based on JavaScript, just few uses pure CSS, but even than some uncommon CSS tricks are used (ie. pointer-events).

I had to do the same, in project I’m working on we got a new layout design and one of the elements to style was nice looking <select> element. I have started looking for solution and after some time had a working one. The problem was it based on those uncommon tricks as pointer-events – this has very big disadvantages – doesn’t work on IE10 and below. You can try to exclude styling for <= IE10 but still you must add a lot of boilerplate to gain a bit.

Also the problem was that there were no clear option how to target only IE10 – right now there is a solution but I haven’t tested it yet.

After spending a lot of hours chasing the internet and applying any possible idea, I gave up! All of them didn’t work as I expected (especially on IE10) so it was time to figure out my own osm!™ solution!

And here you have.

The idea behind is simple – make select background transparent, hide native arrow button and move new styled icon behind it 🙂 I used FontAwesome to get nice looking arrow icon.

The Source

You can grab the source of example project here, below I am going to explain only few important points.

Select

select {
  appearance: none;
  -webkit-appearance: none;
  -moz-appearance: none;
  background: transparent;
}

The CSS code above remove default look&feel of <select> and add transparent background – the first step. It’s also worth notice that the width of select element must be set to 100% to fill the whole space.

Icon

.dropdown:after {
  background: none repeat scroll 0 0 #2CA7E5;
  color: #FFFFFF;

  content: "\f078";
  font-family: 'FontAwesome';
  font-size: 14px;

  padding: 8px;

  position: absolute;
  right: 0;
  top: 0;
  bottom: 0;

  z-index: -1;
}

With this CSS snippet you can generate a nice looking arrow icon. To get icon shape I have used FontAwesome and appropriate content value, you can take a look here for possible options. Next was padding – to center the icon and fill the whole space. And final piece of puzzles: z-index – it moves the icon behind the select so it can still react on user clicks – you don’t need dirty tricks with pointer-events and so on.

Tricks

As I said I won’t use tricks – I lied 😀 It isn’t possible to not use tricks when you want to target broad scope of web browsers, especially IE10 and below. I have to add at least one uncommon CSS selector to hide arrow button on IEs:

select::-ms-expand {
  display: none;
}

The second was to polish L&F on FireFox and hide bad looking outline on options:

select:-moz-focusring {
  color: transparent;
  text-shadow: 0 0 0 #000;
}

Result

Finally, that’s how it looks on different browser:

  • IE8
  • IE9
  • IE10
  • IE11
  • FireFox
  • Chrome
  • Safari

Disadvantage

This solution has one minor problem – when you will have a very long option, it will overflow the arrow icon 🙁 but you can solve it in the same way 🙂