Layout Intermediate

Customizable selects without a JavaScript library

Styling selects used to require JavaScript libraries like Select2 or Choices.js that replace the native element entirely. Now appearance: base-select unlocks full CSS customization of the native select.

Old 15+ lines
1/* JS: replace native select with custom DOM */
2import Choices from 'choices.js';
3new Choices('#my-select', {
4  searchEnabled: false,
5});
6
7/* Plus ~30 lines of custom CSS for
8 .choices__inner, .choices__list, etc. */
Modern
8 lines
1select,
2select ::picker(select) {
3  appearance: base-select;
4}
5
6select option:checked {
7  background: var(--accent);
8}
a fully styled native select
appearance: base-select (Chrome 134+)

Native element

Keep the real select with built-in keyboard navigation, form participation, and accessibility for free.

Top-layer rendering

The dropdown renders in the top layer. No overflow clipping from parent containers.

Zero JS, zero dependencies

Drop the 30 KB library. Style everything with CSS alone: button, list, options, even the selected content.

Browser Support
72%
Chrome Edge Firefox 🔜 Safari 🔜
View on caniuse.com →
Lines Saved
45+ → 8
No JS or lib CSS
Old Approach
JS libraries
Select2, Choices.js
Modern Approach
base-select
appearance: base-select

How it works

Custom-styled selects have been one of the biggest pain points in web development. The native <select> element was essentially un-stylable, so libraries like Select2 and Choices.js replaced it with a fully custom DOM structure. This added weight, broke accessibility, and required constant maintenance.

With appearance: base-select, you opt into the new customizable select mode. The browser provides a minimal, fully stylable foundation. You can style the button, the dropdown (::picker(select)), individual options, and even use the <selectedcontent> element to reflect the selected option's HTML in the button. Rich content like images and icons work inside options natively.

ESC