The <select> element can now be customized with CSS

Published: March 24, 2025

From Chrome 135, web developers and designers can finally unite on an accessible, standardized and CSS styleable <select> element on the web. This has been many years in the making, many hours of engineering and collaborative specification work, and the result is an incredibly rich and powerful component that won't break in older browsers.

Here's a video of customized selects using these new features:

Featuring demos by Una, Brecht, and Adam.

If you've been following along closely, you'll notice a few spec names and features have changed since Una's request for community feedback. Luckily, if you worked from that post and are interested in what's changed, Una's also got you covered.

Meet appearance: base-select

A new CSS property appearance: base-select that puts the <select> element into a new, configurable and styleable state to be commonly referred to as "base" styles:

.custom-select {
  &, &::picker(select) {
    appearance: base-select;    
  }
}

Using base-select unlocks a number of new features and behaviors:

Using base-select loses a number of features and behaviors:

  • The <select> doesn't render outside the browser pane.
  • It doesn't trigger built-in mobile operating system components.
  • The <select> stops taking the width of the longest <option>.

A <select> can now include rich HTML content

Before you could customize a <select>, if you put things like an image or SVG into the <option> element, the browser would ignore them.

Consider the following HTML, the browser would read it as you authored it:

<select class="custom-select">
  <option>
    <svg aria-hidden>…</svg>
    <span>HTML</span>
  </option>
  <option>
    <svg aria-hidden>…</svg>
    <span>CSS</span>
  </option>
  <option>
    <svg aria-hidden>…</svg>
    <span>JavaScript</span>
  </option>
  <option>
    <svg aria-hidden>…</svg>
    <span>WASM</span>
  </option>
</select>

However the used DOM wouldn't include the <svg>:

<select class="custom-select">
  <option>
    <span>HTML</span>
  </option>
  <option>
    <span>CSS</span>
  </option>
  <option>
    <span>JavaScript</span>
  </option>
  <option>
    <span>WASM</span>
  </option>
</select>

Here's (from left to right) Chrome, Safari, and Firefox rendering the preceding HTML. If the browser supports appearance: base-select then the SVG will appear in the option, otherwise it won't.

Chrome, Safari and Firefox shown rendering a select with SVG inside. Chrome shows the images, Safari and Firefox render as if there were no images.
Try it in this Codepen.

There's risk in breaking existing websites with customizable select, due to the parser changes. Chrome has the features behind a Finch experiment in case there is an emergency need to turn it off. If things go well, the experiment will end and the code will be shipped permanently into the source.

Completely customizable

Every part of a base-select can be swapped out, customized and animated. Here's a demo that uses every new feature to create recognizable and meaningful select experiences.

Four different presenations of a select element are shown. The first has a status indicator dot in it that's green, with a label of on. The next shows avatars next to the options. The third is a color space picker with a custom label built into the select. The last allows choosing draft or published states.
Try it in this Codepen.

Find many more examples in the resources section at the end of this post.

Unchanged JavaScript interfaces

There's no risks to your existing JavaScript interactions with a <select> element.

However, if you do begin adding rich HTML into your <option> elements, you should test the selected values, as the browser does still parse and ignore images and SVG. The logic has changed though, for determining the selected content string, and depending on what you have in your options, you may need to make adjustments.

If you're using the value attribute on an <option> you have nothing to worry about.

Resources

Chrome is first to implement base-select, but every browser participated in the specifications, and there's more "base" elements yet to be completed. This is just a start.

Stay tuned as we'll be continuing to add guidance, examples and resources on customizing select elements. Until then, checkout the following links for more information.

Special thanks to all those who were involved in making this happen!