Native <select> elements provide keyboard interaction, form submission, focus behaviour, and platform integration. They are also famously difficult to style.
That tension has pushed many teams to replace a real select with divs, ARIA roles, and a large JavaScript component. The result may match the design system, but it also inherits responsibility for every keyboard, focus, scrolling, and assistive-technology detail.
Customizable select features aim to provide a better middle ground: keep the native element and behaviour while opting into new styling hooks.
Support is still limited. MDN does not classify the complete feature set as Baseline, and framework or server-rendering interactions need testing. Use progressive enhancement rather than replacing every production dropdown immediately.
Opt into the base-select appearance
The central CSS opt-in is appearance: base-select on both the select and its picker.
select,
::picker(select) {
appearance: base-select;
}
This gives the control browser-defined base behaviour that can be styled more directly.
select {
min-inline-size: 14rem;
padding: 0.75rem 1rem;
border: 1px solid #cbd5e1;
border-radius: 0.75rem;
background: white;
color: #0f172a;
}
::picker(select) {
border: 1px solid #cbd5e1;
border-radius: 0.75rem;
box-shadow: 0 1rem 2rem rgb(15 23 42 / 18%);
}
Style the open state
The :open pseudo-class can target the select while its picker is displayed.
select:open {
border-color: #4f46e5;
box-shadow: 0 0 0 3px rgb(79 70 229 / 20%);
}
The picker icon also has a dedicated pseudo-element:
select::picker-icon {
color: #64748b;
transition: rotate 160ms ease;
}
select:open::picker-icon {
rotate: 180deg;
}
Remember to respect reduced-motion preferences if an animation is not essential.
Style options without losing their meaning
Options can receive richer visual treatment in supporting browsers.
option {
padding: 0.75rem 1rem;
}
option:hover,
option:focus {
background: #eef2ff;
}
option:checked {
background: #e0e7ff;
font-weight: 700;
}
::checkmark can style the visual indicator for the selected option, while ::picker-icon targets the closed control's disclosure icon.
Selected content can be richer
The evolving customizable-select model permits a button as the first child of the select and introduces <selectedcontent> to display a clone of the chosen option's content.
<select name="plan">
<button>
<selectedcontent></selectedcontent>
</button>
<option value="starter">
<span aria-hidden="true">🌱</span>
Starter
</option>
<option value="growth">
<span aria-hidden="true">🚀</span>
Growth
</option>
</select>
Keep option labels concise and meaningful without their decorative icons.
Progressive enhancement is the safest rollout
Start with valid, ordinary select markup. Browsers without the new rendering path should retain a usable classic control.
@supports (appearance: base-select) {
select,
::picker(select) {
appearance: base-select;
}
/* Enhanced styling lives here. */
}
Do not hide the select and replace it with an unsupported picker. The fallback is a feature, not a failure.
Framework and hydration risks
Modern parsing rules allow richer children inside a select, but some framework versions may still assume the older content model. Server-rendered markup can also differ from the client-side tree and cause hydration warnings.
Before adopting the richer markup:
- test the exact framework and version
- test server rendering and hydration
- inspect the DOM produced in supporting and non-supporting browsers
- keep a classic markup variant if your framework cannot preserve the structure
CSS-only enhancement of a normal select is a smaller first step than immediately using every new element and pseudo-element.
Accessibility testing remains necessary
Native semantics reduce risk, but visual customization can still create problems.
Check:
- visible focus indication
- keyboard selection and dismissal
- high-contrast and forced-colors modes
- zoom and text resizing
- long labels and localization
- disabled options and optgroups
- screen-reader announcements
- touch target size
Do not remove outlines without providing an equally strong focus indicator.
When to keep a custom component
A select is appropriate when a user chooses from a list of options. It is not automatically a replacement for every combobox, searchable command palette, tree picker, or multi-step menu.
If your interface needs asynchronous search, arbitrary text input, virtualized results, or complex option actions, a purpose-built component may still be necessary. Use the semantic pattern that matches the interaction.
A safe migration plan
- Choose one simple single-select field.
- Keep the current native markup.
- Add
base-selectstyling inside@supports. - Test all required browsers and assistive technologies.
- Introduce richer option content only after framework and hydration checks pass.
- Preserve the ordinary native control as the fallback.
Conclusion
Customizable select is exciting because it may finally reduce the trade-off between design control and native behaviour.
The best adoption strategy is incremental. Improve a real select where support exists, keep the classic control everywhere else, and let accessibility and compatibility tests—not a screenshot—decide whether the result is ready.
Sources:
- https://developer.mozilla.org/en-US/docs/Learn_web_development/Extensions/Forms/Customizable_select
- https://developer.mozilla.org/en-US/docs/Web/CSS/appearance
- https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/select
- https://webkit.org/blog/17967/news-from-wwdc26-webkit-in-safari-27-beta/
Top comments (0)