
27 September 2026 · 10 min
Custom selects: design freedom without accessibility debt
Safari 27 makes native select controls deeply styleable. Here is how to adopt the new CSS progressively, keep keyboard and form behaviour, and avoid rebuilding the old dropdown problems.




A small UI control with surprisingly high costs
A dropdown looks trivial in a design file: a field, an arrow and a list. In development it is often the opposite. As soon as a team replaces the native select element with a custom menu, it takes ownership of work the browser used to do quietly: keyboard navigation, focus, mobile interaction, screen-reader information, form values, validation, reset behaviour and long lists.
On 17 September 2026, WebKit released Safari 27. Its new features include customizable native select elements and scroll anchoring. The select work is particularly relevant to product teams: the real form control can now be styled much more deeply without throwing away its built-in semantics.
This is not an invitation to turn every choice into a tiny art project. It is an opportunity to ship less JavaScript while still creating an interface that belongs to the brand.
What changed under the hood
The new approach still starts with a normal select and normal option elements. That is the important part. The form knows the value, the keyboard understands the choice and assistive technology receives a familiar control.
With appearance: base-select, supporting browsers can switch to a new rendering mode. Several CSS building blocks sit on top of it:
- ::picker(select) styles the open picker;
- ::picker-icon targets the arrow in the closed control;
- ::checkmark styles the selected-option marker;
- :open describes the state while the list is open;
- selectedcontent can render the chosen option inside the field's button.
Options may contain more than a plain text line. A product can show a small icon, a title and supporting information for shipping methods, team roles, locations or plans. The underlying choice remains a native form control.
The golden rule: every option needs an understandable name
WebKit gives customizable selects one simple rule: every option must retain text or an accessible text name. An icon alone is not enough. A flag does not name a country, a coloured dot does not explain a status and a parcel symbol does not identify a shipping service.
That rule helps in three ways:
- A screen reader can announce the option.
- If CSS fails or the browser does not support the new presentation, the fallback remains readable.
- People do not have to guess what symbols mean.
The visual layer should add to the name, not replace it. “Express · tomorrow” next to a lightning icon works. The lightning icon by itself does not.
Progressive enhancement, not browser roulette
MDN still marks the technology as limited availability. That is not a reason to avoid it; it is an implementation instruction. The classic select must work first. The richer presentation arrives as an additional CSS layer.
A robust sequence looks like this:
- Build a semantic select with a label, name, values and readable options.
- Test keyboard use, form submission, validation and errors without custom styles.
- Enable the new mode only in browsers that understand it.
- Test the enhanced presentation with long content and real data.
- Deliberately accept the native default in browsers without support.
The result does not have to be pixel-identical everywhere. It has to stay clear, usable and sufficiently on-brand everywhere. Trying to force the fallback to match every pixel often leads straight back to a complete JavaScript widget — and to the risks we were trying to remove.
A practical use case
Consider a delivery selector in checkout. Three choices need to show price, expected arrival and a short explanation. Historically there were two poor extremes: a narrow default select with too little context or three fully custom cards with their own selection and focus logic.
A customizable select can sit between them. Closed, it shows “Standard · 2–3 working days”. Open, each option has an icon, name, timeframe and price. The browser still owns the selected value and submits it with the form.
The demo does not decide whether that is better. Tasks do. Can people find the right option faster? Do they understand the price difference? Can they change the choice using only the keyboard? Is the page still clear at 200 percent zoom? Only those answers justify the richer presentation.
The states that disappear from mock-ups
A beautiful resting state represents only a fraction of the work. For a production select, we design and test at least:
- default, hover, focus-visible and open;
- selected, empty, invalid and disabled;
- disabled options and option groups;
- long German labels and narrow mobile viewports;
- high zoom, strong contrast and reduced motion;
- error messages, help text and the associated label;
- form reset and reloading saved values.
Motion should explain state, not delay interaction. A short colour or shadow transition is often enough. If the list uses a large spatial animation, it needs a calm alternative for prefers-reduced-motion.
A test matrix that finds more than a screenshot
For every new select, we walk through the interaction as a small journey:
Keyboard: Tab reaches the field. Arrow keys change values sensibly. Enter, Space and Escape behave as expected. Focus never disappears behind a custom layer.
Screen reader: The label, current value, state and options are announced clearly. Decorative icons do not duplicate information.
Form: Submission, server validation, browser validation, reset and prefilled values produce the same value as the unstyled select.
Browser: Supporting browsers show the enhanced treatment. Other browsers retain a completely usable native control. With CSS disabled, options remain in a logical order.
Content: Long copy, translations, special characters, many options and dynamically loaded values do not break the layout or the selection.
With React, Vue or another UI framework, test a real production build as well. Tooling does not always accept new HTML structures at the same time as browsers; a feature has only reached the product when rendering, hydration and tests all handle it cleanly.
The other Safari 27 detail: scroll anchoring
Safari 27 also enables scroll anchoring. When content appears late above the current reading position, the browser tries to keep the visible section stable. That reduces the familiar jump caused by late images, notices or asynchronous components.
The best solution is still to reserve space early: give images width and height, make skeletons roughly match the final content and place firm bounds around advertising slots. Scroll anchoring is a safety net, not a replacement for stable layout.
Do not disable overflow-anchor globally. Use overflow-anchor: none only for a specific area where the application intentionally controls position, such as a custom chat timeline. Otherwise, the product removes a browser feature that was protecting the reader's place.
Our seven-step rollout
- Pick one existing, troublesome dropdown — not the entire component library.
- Make native semantics and form data the source of truth again.
- Secure a readable fallback without the new CSS features.
- Add the richer presentation as a progressive layer.
- Run the complete state and accessibility matrix.
- Test on real mobile devices and with long translations.
- After release, watch error rates, abandonment and support questions.
Less widget, more product
The most interesting part of customizable selects is not that dropdowns can finally look better. It moves the boundary between browser and product team to a healthier place. The browser keeps the difficult foundation; the team designs information, hierarchy and brand.
That is how modern front-end work should feel: native capability first, progressive refinement on top and JavaScript only where it creates a real additional benefit.
Sources



