How to Style a <select> Box Drop-down with Only CSS?

It has been hard for a long time to style the <select> element across all browsers.

To avoid the weaknesses it had in the past, use things like styling a parent element, adding pseudo-elements, and also applying JavaScript.

A reasonable set of styles, as it turns out, can create a consistent and attractive selection box across new browsers while remaining just fine in older ones as well.

There are several elements of a select box that we can be styled, particularly the width, height, font, border, color, padding, box-shadow and background color.

Box Drop-down Styling

Example of styling a select box:

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
    <style>
      .box {
        width: 120px;
        height: 30px;
        border: 1px solid #999;
        font-size: 18px;
        color: #1c87c9;
        background-color: #eee;
        border-radius: 5px;
        box-shadow: 4px 4px #ccc;
      }
    </style>
  </head>
  <body>
    <p>An ordinary select box:</p>
    <select>
      <option>Coffee</option>
      <option>Tea</option>
      <option>Juice</option>
      <option selected>Cocktail</option>
    </select>
    <p>A styled select box:</p>
    <select class="box">
      <option>Coffee</option>
      <option>Tea</option>
      <option>Juice</option>
      <option selected>Cocktail</option>
    </select>
  </body>
</html>

However, the annoying drop-down arrow continually stays the same. There is no direct way to style it, but there are some tricks that can be used to change the default drop-down arrow. Let’s discuss the three methods below.

1) Use appearance: none;

In order to hide the default arrow of the <select> dropdown, set the appearance CSS property to its "none" value, then add your individual arrow with the help of the background shorthand property.

Note that the appearance property is still considered to be an experimental technology and you need to use -moz- (for Firefox) and -webkit- (for Chrome, Safari, Opera) prefixes for maximum browser compatibility.

Example of adding an individual arrow:

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
    <style>
      select {
        width: 140px;
        height: 35px;
        padding: 5px 35px 5px 5px;
        font-size: 18px;
        border: 2px solid #ccc;
        -webkit-appearance: none;
        -moz-appearance: none;
        appearance: none;
        background: url("/uploads/media/default/0001/02/f7b4d3d2ba3fe1d8518e6e63d7740e1e73921abf.png") 96% / 15% no-repeat #eee;
      }
      select::-ms-expand {
        display: none;
        /* remove default arrow in IE 10 and 11 */
      }
    </style>
  </head>
  <body>
    <select>
      <option>Coffee</option>
      <option>Tea</option>
      <option>Juice</option>
      <option selected>Cocktail</option>
    </select>
  </body>
</html>

2) Use overflow: hidden;

First, put the <select> box element in a div container with a fixed width and set overflow: hidden. Then, give the <select> element a width of more than 20 pixels larger than the <div> element. This will make the default drop-down arrow become hidden (because of the overflow: hidden on the container), and now it is possible to apply a background image on the right side of the <div>.

This method is good to use because all browsers effectively support overflow: hidden.
Note that the disadvantage of this method is that the options are visually more extended than the select menu.

Example of adding an individual arrow:

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
    <style>
      .mystyle select {
        background: transparent;
        width: 140px;
        height: 35px;
        border: 1px solid #ccc;
        font-size: 18px;
      }
      .mystyle {
        width: 120px;
        height: 34px;
        border: 1px solid #111;
        border-radius: 3px;
        overflow: hidden;
        background: url("/uploads/media/default/0001/02/f7b4d3d2ba3fe1d8518e6e63d7740e1e73921abf.png") 96% / 20% no-repeat #ddd;
      }
    </style>
  </head>
  <body>
    <div class="mystyle">
      <select>
        <option>Coffee</option>
        <option>Tea</option>
        <option>Juice</option>
        <option selected>Cocktail</option>
      </select>
    </div>
  </body>
</html>

3) Use pointer-events: none;

The CSS pointer-events property can be used to create individual <select> dropdowns, by overlaying an element over the native drop-down arrow (to create the custom one) and disallowing pointer-events on it.

This method works well and has excellent browser support.

Example of creating an individual drop-down using the pointer-events property:

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
    <style>
      .mybox {
        position: relative;
        display: inline-block;
      }
      select {
        display: inline-block;
        height: 30px;
        width: 150px;
        outline: none;
        color: #74646e;
        border: 1px solid #ccc;
        border-radius: 5px;
        box-shadow: 1px 1px 2px #999;
        background: #eee;
      }
      /* Select arrow styling */
      .mybox .myarrow {
        width: 23px;
        height: 28px;
        position: absolute;
        display: inline-block;
        top: 1px;
        right: 3px;
        background: url("/uploads/media/default/0001/02/f7b4d3d2ba3fe1d8518e6e63d7740e1e73921abf.png") right / 90% no-repeat #eee;
        pointer-events: none;
      }
    </style>
  </head>
  <body>
    <div class="mybox">
      <span class="myarrow"></span>
      <select>
        <option>Coffee</option>
        <option>Tea</option>
        <option>Juice</option>
        <option selected>Cocktail</option>
      </select>
    </div>
  </body>
</html>

4) Use Punctuation Marks Instead of the Drop-down Arrow

It is quite pretty to use your preferred marks instead of the annoying drop-down sign of the <select> box.

Set the marks in the content property and set the corresponding font to look good. Here, we set "Consolas" and "monospace". Then, you need to rotate the punctuation marks using the CSS transform property.

Here, the <select> box is inserted in a <label> element, so that we can set a cursor for it even if the pointer-events property is set to "none".

Example of using a punctuation mark instead of the drop-down arrow:

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
    <style>
      select {
        width: 140px;
        height: 35px;
        padding: 4px;
        border-radius: 4px;
        box-shadow: 2px 2px 8px #999;
        background: #eee;
        border: none;
        outline: none;
        display: inline-block;
        -webkit-appearance: none;
        -moz-appearance: none;
        appearance: none;
        cursor: pointer;
      }
      label {
        position: relative;
      }
      label:after {
        content: '<>';
        font: 11px "Consolas", monospace;
        color: #666;
        -webkit-transform: rotate(90deg);
        -moz-transform: rotate(90deg);
        -ms-transform: rotate(90deg);
        transform: rotate(90deg);
        right: 8px;
        top: 2px;
        padding: 0 0 2px;
        border-bottom: 1px solid #ddd;
        position: absolute;
        pointer-events: none;
      }
      label:before {
        content: '';
        right: 6px;
        top: 0px;
        width: 20px;
        height: 20px;
        background: #eee;
        position: absolute;
        pointer-events: none;
        display: block;
      }
    </style>
  </head>
  <body>
    <label>
      <select>
        <option>Coffee</option>
        <option>Tea</option>
        <option>Juice</option>
        <option selected>Cocktail</option>
      </select>
    </label>
  </body>
</html>

Do you find this helpful?

Related articles