Apr 13, 2019

How to Create a Flat Select Element that is consistent in all browsers?

Form elements looking different across browsers is a well-known problem, but the <select> element is especially problematic in this regard. If I try to change the default styling of <select> by increasing its height (which, by default, is too small), the dropdown menu starts to look drastically different in all major browsers. Not to mention that it’s plain ugly in Firefox and Safari.

image

What we need is a good-looking Select element that is consistent across all browsers.

If you wish, you can skip the tutorial and directly use the Select element from here.

appearance to the rescue

By default, the form elements’ theming depends upon how the operating system native UI controls look like. Using the appearance property, you can change how they appear. For eg, -webkit-appearance: checkbox; applied to any form element will make it look like a checkbox.

Not that useful? Yeah, maybe, but we need appearance property to remove the default styling of Select element. Because the CSS spec for appearance is still work in progress, we need to use vendor prefixes. The following CSS propertoes would hide the native UI styles that get applied to the Select element.

{
    -webkit-appearance:none;
    -moz-appearance:none;
    -ms-appearance:none;
    appearance: none;
}

Flattening and Making Select Look Good

To do this, we will be setting CSS properties for background, border, padding, and height. Of course, the choice of colors depends upon how your page is currently styled.

{
    height: 40px;
    padding: 0 28px 0 8px;
    border: 1px solid #ccc;
    outline: 0;
    font-size: 14px;
    border-radius: 0;
}

Adding the Arrow

The only thing to add is the dropdown arrow, which can be done by using the background property. We will be using data URIs and background-position to achieve this. The SVG is used here is a downward arrow icon.

{
    background: url('data:image/svg+xml;charset=US-ASCII,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22292.4%22%20height%3D%22292.4%22%3E%3Cpath%20fill%3D%22%23000%22%20d%3D%22M287%2069.4a17.6%2017.6%200%200%200-13-5.4H18.4c-5%200-9.3%201.8-12.9%205.4A17.6%2017.6%200%200%200%200%2082.2c0%205%201.8%209.3%205.4%2012.9l128%20127.9c3.6%203.6%207.8%205.4%2012.8%205.4s9.2-1.8%2012.8-5.4L287%2095c3.5-3.5%205.4-7.8%205.4-12.8%200-5-1.9-9.2-5.5-12.8z%22%2F%3E%3C%2Fsvg%3E') no-repeat, #fff;
    background-position: 98% 50%;
    background-size: 8px;
}

Fixing Outline in Mozilla Firefox

One last issue we need to fix is a dotted outline being added to the dropdown options in Firefox. This can be fixed by:

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

Final CSS

Here’s our final CSS and the result can be seen here. It’ll be consistent across most major browsers. This won’t work in IE11, but considering that its usage is around 2% and declining everyday, I think it’s a safe choice.

select {
    -webkit-appearance:none;
    -moz-appearance:none;
    -ms-appearance:none;
    appearance: none;

    height: 40px;
    padding: 0 28px 0 8px;
    border: 1px solid #ccc;
    outline: 0;
    font-size: 14px;
    border-radius: 0;

    background: url('data:image/svg+xml;charset=US-ASCII,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22292.4%22%20height%3D%22292.4%22%3E%3Cpath%20fill%3D%22%23000%22%20d%3D%22M287%2069.4a17.6%2017.6%200%200%200-13-5.4H18.4c-5%200-9.3%201.8-12.9%205.4A17.6%2017.6%200%200%200%200%2082.2c0%205%201.8%209.3%205.4%2012.9l128%20127.9c3.6%203.6%207.8%205.4%2012.8%205.4s9.2-1.8%2012.8-5.4L287%2095c3.5-3.5%205.4-7.8%205.4-12.8%200-5-1.9-9.2-5.5-12.8z%22%2F%3E%3C%2Fsvg%3E') no-repeat, #fff;
    background-position: 98% 50%;
    background-size: 8px;
}

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

Follow Me!

I write about things that I find interesting. If you're modestly geeky, chances are you'll find them too.

Subscribe to this blog via RSS Feed.

Don't have an RSS reader? Use Blogtrottr to get an email notification when I publish a new post.