UI/UX and dev is always a delicate balance. We had a recent request come in to style our dropdowns as the rest of our form fields. We are using bootstrap so our inputs are fairly customized. Here is how I did it, I will discuss the issues and caveats after the basic code for “modern” browsers.

HTML structure

    <select>
        <option value="1">Value 1</option>
        <option value="2">Value 2</option>
        <option value="3">Value 3</option>
        <option value="4">Value 4</option>
    </select>
</label>

This is all in less.

Style the containing label:

.custom-select {
    position: relative;

    &:after {
        .fa; //Font awesome icon
        .input-group-addon; //bootstrap mixin
        border-bottom-left-radius: 0;
        border-top-left-radius: 0;
        padding: 10px 13px;
        width: auto;
        height: 100%;
        content: "\f107"; //down arrow
        font-family: FontAwesome;
        position: absolute;
        right: 15px;
        top: 0px;
        pointer-events: none; //Do not block the propagation of the pointer event
    }

Now to style the select box itself which is really just hiding the arrows and coloring it.

select {
        outline: none; //hide the outline
        -webkit-appearance: none; //hide the arrows
        -moz-appearance: none; //hide the arrows
        appearance: none; //hide the arrows
        cursor: pointer; //change the cursor
        .placeholder(); //mixin for placeholder values
        color: @input-color; //theme var
        font-weight: normal;

        option {
            color: @input-color; //background for the options
        }
    }
    /* Targetting Webkit browsers only. FF will show the dropdown arrow with so much padding. */
    @media screen and (-webkit-min-device-pixel-ratio:0) {
        select {
            padding-right: 18px;
        }
    }
}

Relatively simple, but there are some key pieces that need to be in place for this to work.

  • pointer-event: none; This is very important or the overlaid addon would catch the pointer even and we wouldn’t “click through” to the underlying select box. This is NOT SUPPORTED by anything less than IE11. (IE10 is still going to cause you fits here).
  • `outline: none; //hide the outline
  • -webkit-appearance: none; //hide the arrows
  • -moz-appearance: none; //hide the arrows
  • appearance: none; //hide the arrows
  • cursor: pointer; //change the cursor Also very important so we don’t see the stupid OS generated select boxes that change from one to the next.

You will probably also notice that I don’t touch any of the nasty hacks that could happen for IE8-10. This is because I used a bit of javascript to grab these boxes and just remove all custom styling. It is much easier than hacking it and we have decided it to be graceful degradation. I will discuss this in a different post.

Your output should look something like this:

Custom_Select

Unlike some examples i’ve seen out on the internet here is an actual WORKING example of how this is supposed to look and behave in modern browsers.