The native select HTML elements don’t tend to be very good looking. And they don’t support much CSS either, so the designers and developers go for hacks. Like the one in this article.

The technique is perfectly explained by the inspiring Lea Verou, and it’s based on ‘replacing’ the native dropdown arrow with a custom element. We can then set the pointer-events of the new elements to none in order to let the events be triggered on the select element.

The HTML

We need to wrap our <select> inside another HTML element:

html
<div class="select">
    <span class="arr"></span>
    <select>
      <option>All about that bass</option>
      <option>Dear Future Husband</option>
      <option>Close Your Eyes</option>
    </select>
  </div>

We could add the new dropdown arrow as an element here as well, but let’s use the CSS pseudo classes this time. (The options text are some song titles from Meghan Trainor’s Title. We also add a span element, which will hide the native dropdown in non-webkit browsers.

The CSS

Let’s style the wrapping element first:

css
.select {
  font-size: 16px;
  position: relative;
  display: inline-block;
}

We give the wrapping div a position: relative, so that we can place the new dropdown element absolutely inside it. The inline-box display will wrap the element around the size of the select box.

The select box is styled as follows:

css
.select select {
  outline: none;
  -webkit-appearance: none;
  display: block;
  padding: 1.2em 3em 1.3em 1.5em;
  margin: 0;

  transition: border-color 0.2s;
  border: 5px solid #EB5168;
  border-radius: 5px;

  background: #fff;
  color: #555;
  line-height: normal;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
}

The important bit here is -webkit-appearance: none, which will hide the native dropdown arrow. Now we need to create the new, custom, arrow:

css
.select .arr {
  background: #fff;
  bottom: 5px;
  position: absolute;
  right: 5px;
  top: 5px;
  width: 50px;
  pointer-events: none;
}
.select .arr:before {
  content: '';
  position: absolute;
  top: 50%;
  right: 24px;
  margin-top: -5px;
  pointer-events: none;
  border-top: 10px solid #EB5168;
  border-left: 10px solid transparent;
  border-right: 10px solid transparent;
}

.select .arr:after {
  content: '';
  position: absolute;
  top: 50%;
  right: 28px;
  margin-top: -5px;
  pointer-events: none;
  border-top: 6px solid #fff;
  border-left: 6px solid transparent;
  border-right: 6px solid transparent;
}

The code above will create an arrow in the same colour as the border of the select box (You can see how to generate these arrows at caret). The arrow will not respond to click events, as we have disabled them by specifying pointer-events: none. The arrow is within the span element, as we need to a 'physical' DOM element to hide the native dropdown arrow.

Now we have our nicely designed select box. Check this tutorial’s code in github.

Happy coding!