DEV Community

Cover image for Customizable Select: The <select> dropdown FINALLY catches up with CSS
Olivier Leplus
Olivier Leplus

Posted on

Customizable Select: The <select> dropdown FINALLY catches up with CSS

Style native dropdowns with CSS, from the picker and checkmark to options with rich HTML. Explore current browser support and three practical examples that keep the browser’s built-in selection behavior.

Why this feature exists

For years, <select> was easy to use and frustrating to style. Its popup and other internals often belonged to the operating system; appearance: none could remove some styling, but it did not give you full control over the dropdown. Matching a design often meant rebuilding the control in JavaScript, including its keyboard interaction, focus management, and accessibility.

Customizable select addresses that gap by extending the existing HTML element. You opt in with the new appearance: base-select value, then style the picker, options, arrow, and checkmark with CSS. Native form submission and selection behavior remain available; richer markup lets you add things like icons and color swatches.

Browser support today

Checked September 22, 2026. Support for the single-selection dropdown features used below:

Browser Status
Chrome and Edge Shipped in 135+. Chrome announcement · compatibility data
Chrome for Android Supported in current releases. Compatibility data
Safari on macOS, iOS, and iPadOS Shipped in 27.0, released September 17, 2026. WebKit release notes
Firefox Not enabled by default; implementation is still experimental. Mozilla status

This is not yet Baseline. Use it as progressive enhancement: unsupported browsers should still get an ordinary, usable select. Safari 27 also introduces different base styles, so do not expect unstyled defaults to look identical across engines.

1. Opt in with one CSS value

Start with familiar HTML:

<label for="mode">Reading mode</label>
<select id="mode" name="mode">
  <option value="standard">Standard</option>
  <option value="focus" selected>Focus</option>
  <option value="compact">Compact</option>
</select>
Enter fullscreen mode Exit fullscreen mode
select,
select::picker(select) {
  appearance: base-select;
}
Enter fullscreen mode Exit fullscreen mode

select targets the control; ::picker(select) targets its popup. Opt in both to customize both. No replacement HTML component or JavaScript is needed.

Basic customizable select: Focus selected in the closed control on the left, and the native base-style menu open on the right.

Screenshots use Chromium 153.0.8010.0. The surrounding layout and typography are presentation styles; runnable examples are in the accompanying examples folder.

2. Style the picker, arrow, and selected option

Keep the same HTML and replace the CSS with this:

@supports (appearance: base-select) {
  select,
  select::picker(select) {
    appearance: base-select;
    font: 1rem/1.5 system-ui;
    color: #262139;
    background: #fff;
    border: 1px solid #c9c2dc;
    border-radius: 12px;
  }

  select { min-width: 240px; padding: 12px 16px; }
  select::picker(select) {
    margin-top: 8px;
    padding: 6px;
    box-shadow: 0 12px 28px #26213926;
  }

  option { padding: 10px 12px; border-radius: 7px; }
  option:checked { background: #ede9fe; color: #5b21b6; }
  option:hover,
  option:focus-visible { background: #f3f0ff; }

  select:focus-visible,
  option:focus-visible { outline: 2px solid #7c3aed; }
  select:focus-visible { outline-offset: 3px; }
  option:focus-visible { outline-offset: -2px; }

  select::picker-icon { color: #7c3aed; }
  select:open::picker-icon { rotate: 180deg; }
  option::checkmark { color: #7c3aed; }
}
Enter fullscreen mode Exit fullscreen mode

option:checked identifies the current selection. ::picker-icon targets the arrow, :open tracks the open state, and option::checkmark styles the selection marker. The @supports block keeps these enhancements out of browsers that lack the opt-in value.

Styled customizable select with rounded corners, a violet arrow, a shadow beneath the open picker, and a highlighted Focus option.

3. Add rich option content

Now replace the HTML with a color selector. The optional first-child <button> contains <selectedcontent>, which the browser fills with a clone of the selected option’s content.

<label for="accent">Accent color</label>
<select id="accent" name="accent">
  <button type="button">
    <selectedcontent></selectedcontent>
  </button>
  <option value="violet" selected>
    <span class="swatch" style="--color: #7c3aed" aria-hidden="true"></span>
    <span>Violet</span>
  </option>
  <option value="mint">
    <span class="swatch" style="--color: #059669" aria-hidden="true"></span>
    <span>Mint</span>
  </option>
  <option value="coral">
    <span class="swatch" style="--color: #e76f51" aria-hidden="true"></span>
    <span>Coral</span>
  </option>
</select>
Enter fullscreen mode Exit fullscreen mode

Keep the CSS from example 2 and add:

@supports (appearance: base-select) {
  option,
  selectedcontent { display: flex; align-items: center; gap: 10px; }

  .swatch {
    display: inline-block;
    width: 20px;
    height: 20px;
    flex-shrink: 0;
    border-radius: 50%;
    background: var(--color);
    border: 1px solid #0002;
  }

  option::checkmark { order: 1; margin-left: auto; }
}
Enter fullscreen mode Exit fullscreen mode

Rich customizable select with Violet, Mint, and Coral color swatches; the selected Violet swatch also appears in the closed control.

Choose Mint and the browser updates both the swatch and text in the button. Explicit value attributes keep submitted data predictable; decorative swatches are hidden from assistive technology, and every option retains a readable label.

Keep the native fallback useful

Keep text in every option, even when adding icons or images. These examples retain meaningful choices without the enhanced styling. Continue using a proper <label>, visible keyboard focus, and non-interactive option content.

Two details matter when integrating this into an app:

  • Mobile behavior changes: an opted-in picker stays inside the browser viewport and replaces the operating system’s usual picker. Test it on touch devices. Chrome details
  • Frameworks need checking: rich select markup can expose parser or SSR hydration issues. Test your framework and assistive-technology combinations. Native semantics are a foundation, not a substitute for testing. MDN guidance

Top comments (0)