Customizable Select: Style the Real <select> at Last

Going beyond the default select element has meant one of two bad trades: heavy JavaScript libraries or lots of div elements, with accessibility getting tricky either way.1 At WWDC 2026, the Safari team showed the way out: customizable select, a set of HTML and CSS additions that make the pre-existing <select> element completely stylable while keeping the semantics, keyboard navigation, and screen-reader support it already provides. Starting in Safari 27 and Chrome 135, you can restyle the button, the drop-down menu, the checkmark, and even the arrow, then put images, videos, or emojis inside your options.1

TL;DR

  • Customizable select styles the real <select> element with HTML and CSS alone, replacing the JavaScript libraries and div stacks developers reached for before. Availability starts in Safari 27 and Chrome 135.1
  • The opt-in is appearance: base-select, applied twice: once on the select itself to open up button styling, and once on ::picker(select) to opt out of the native drop-down menu.1
  • New styleable parts ship alongside it: ::picker-icon restyles the arrow via the content property and a width, ::checkmark on the option element swaps the check the same way, and the :open pseudo-class styles the button while the menu is open.1
  • Options accept any kind of content: images, videos, emojis. The session demo puts an SVG and a label inside each option, then lays the whole drop-down out as a CSS grid with grid-template and gap.1
  • Placing a <button> as the first child of <select>, previously not allowed in HTML, replaces the built-in button; the <selectedcontent> element inside it displays the selected option’s rich content.2
  • Progressive enhancement comes free: browsers without support fall back to the native pop-up, and the semantic select element keeps its built-in accessibility everywhere.1

From div soup back to semantic HTML

Watch on Apple Developer ↗

Tim, a Safari engineer, applies appearance: base-select to a photographer-portfolio demo starting at 2:48.

The session’s framing starts from what <select> already does well. The element gives basic accessibility right out of the box: keyboard navigation across option elements and solid screen-reader behavior, all without external libraries.1 On Apple platforms the native rendering is the familiar pull down button, and it matches every other control on the platform, which gives users a known way to navigate it.1

The catch has always been design. Drop the native control onto a styled site and it feels out of place; it refuses to blend in. Until now the fix meant abandoning the element entirely for a JavaScript widget or a pile of divs, and rebuilding the accessibility by hand. Customizable select keeps the element and hands you the styling, in three stages the session walks through on a real photographer-portfolio build: the button, the drop-down menu, and finally content that goes beyond plain text.1

Styling the button: base-select, ::picker-icon, and :open

The button is the part of the select you click to show the menu, and the first step is a single declaration:

select {
  appearance: base-select;
}

appearance: base-select swaps the native rendering for a smaller set of base styles you can change.1 The effect shows up immediately through inheritance: the demo site sets font-family: Gill Sans on the body, and the select button now inherits the body font, matching the label beside it.1 From there, background, border, and padding adjust like any other element.

Two new hooks finish the button. The arrow gets its own selector, ::picker-icon, which takes a content property for a replacement glyph and a width to size it. The :open pseudo-class styles the button differently while the drop-down menu is open:

select::picker-icon {
  content: "▼"; /* swap in your own glyph */
  width: 1rem;
}

select:open {
  background: #1d1d1f;
  color: #f5f5f7;
}

select:open::picker-icon {
  color: #f5f5f7; /* arrow matches the text color in the open state */
}

The session’s verdict on the result: a select matching the rest of the site in only a few lines of CSS.1

Styling the drop-down: ::picker(select) and ::checkmark

The menu comes with styleable parts of its own. You address the drop-down itself with ::picker(select) on the select element, and the check with ::checkmark on the option element.1 Opting out of the native menu requires appearance: base-select a second time, now on the picker:

select::picker(select) {
  appearance: base-select;
  padding: 0.5rem;
  margin-top: 0.25rem;
  border: 1px solid #d2d2d7;
  box-shadow: 0 8px 24px rgb(0 0 0 / 0.12);
}

With the clean slate in place, the demo arranges spacing with padding and margin, then handles borders and a box-shadow on the drop-down.1 Emphasizing the current choice uses the pre-existing :checked selector rather than anything new: bold the checked option, gray out the others.1

option:checked {
  font-weight: bold;
}

option:not(:checked) {
  color: #6e6e73;
}

option::checkmark {
  content: "✓";
  width: 1rem;
}

::checkmark works exactly like ::picker-icon: set content and a width, and the default check becomes whatever glyph fits your design.1

Rich content in options, laid out as a grid

The bigger shift is what goes inside <option>. The session is explicit: any kind of content works, images, videos, emojis, whatever you like.1 The demo builds a category browser for the photographer’s most popular subjects, with an SVG symbol and a label inside each option:

<select>
  <option value="flowers">
    <img src="flowers.svg" alt="">
    Flowers
  </option>
  <!-- more categories -->
</select>

Note the empty alt. Tim leaves the image alt text empty deliberately, because the “Flowers” label would otherwise be called out twice on screen readers.1 Small detail, real consequence: rich options stay as usable with assistive tech as plain ones.

With the default checkmark removed, the demo highlights the selected option through the checked selector and color changes instead.1 One problem remains: symbol-and-label options make the drop-down very long. The fix reuses CSS that already exists, because the picker is now an ordinary styling target. A grid layout reshapes the whole menu:

select::picker(select) {
  display: grid;
  grid-template: 1fr 1fr / 1fr 1fr 1fr; /* rows / columns */
  gap: 0.5rem;
}

grid-template defines the number of rows and columns, while gap defines the spacing between the grid cells, and the drop-down snaps into an organized grid of categories.1 The session ends with a flourish on the same theme: a radial color picker, built entirely with customizable select.1

The swappable button and selectedcontent

One gap remains in the category browser: the SVG symbols live in the options, but the button that shows the current selection only displays text.1 Customizable select closes the gap by letting you replace the built-in button, placing a <button> element as the first child of the <select>. Putting a button inside a select was previously not allowed in HTML; now it accepts custom content, like labels, or like the element built for exactly this job.1

WebKit’s Safari 27 beta announcement names that element: <selectedcontent>. Placed inside the select’s first-child button, it displays the currently selected option’s content and can be styled directly.2

<select>
  <button>
    <selectedcontent></selectedcontent>
  </button>
  <option value="everything">
    <img src="everything.svg" alt="">
    Everything
  </option>
  <!-- more categories -->
</select>

The element mirrors whatever rich content belongs to the selected option, like the SVG next to the “Everything” label in the demo, so the button finally shows the same visual language as the menu it opens.12

Progressive enhancement is built in

The last step in the session is the one teams skip at their peril: checking the design in browsers that don’t support customizable select. The answer is the best kind of boring. Progressive enhancement kicks in, the control stays usable, and customers get the native pop-up.1 Reusing the select element means the fallback story already exists, and because <select> is a semantic element, the built-in accessibility features survive in every browser.1

Availability is concrete: Safari 27 and Chrome 135. To try the features now, download Safari Technology Preview or Safari Beta.1 The session’s closing guidance is practical: check the demo on webkit.org, style something simple on your own site, test in browsers without support and with assistive tools, and read WebKit’s best-practices material so the interface works for everyone.1

Key Takeaways

For frontend developers: - Opt in with appearance: base-select on the select element for the button, and again on ::picker(select) for the drop-down; then style background, border, padding, spacing, and box-shadow like any other element.1 - Swap the arrow with ::picker-icon and the check with ::checkmark, both via content plus width; style the open state with :open; emphasize the selection with the pre-existing :checked selector.1 - Put real HTML inside <option> (images, videos, emojis) and reshape the menu with existing CSS, like a grid-template plus gap grid; replace the built-in button with a first-child <button> holding <selectedcontent>.12

For accessibility-minded teams: - The semantic select keeps keyboard navigation and screen-reader support without external libraries, in supported and unsupported browsers alike.1 - When options carry both an image and a text label, leave the image alt text empty so screen readers don’t announce the label twice.1 - Test with browsers that lack support and with assistive tools before shipping, per the session’s own checklist.1

For technical leads planning rollout: - Treat customizable select as a progressive enhancement: Safari 27 and Chrome 135 get the custom design, everyone else gets the native pop-up, and no JavaScript fallback is required.1 - Evaluate it now in Safari Technology Preview or Safari Beta, and weigh it against the drop-down library currently sitting in your bundle.1

FAQ

What is customizable select?

Customizable select is a set of HTML and CSS capabilities, introduced by the Safari team at WWDC 2026 and starting in Safari 27 and Chrome 135, that makes the pre-existing <select> element completely customizable. You style the button, drop-down menu, arrow, and checkmark with CSS, and put rich content inside options, while keeping the element’s built-in accessibility.1

How do I opt in to customizable select?

Apply appearance: base-select in two places: on the select element itself, which replaces the native button rendering with a smaller set of base styles, and on ::picker(select), which opts the drop-down menu out of its native rendering so you can style it freely.1

Can I put images or other HTML inside option elements?

Yes. The session states you can put any kind of content inside options: images, videos, emojis. The demo uses an SVG and a text label per option, with empty image alt text so screen readers announce the label only once, and lays the menu out as a CSS grid using grid-template and gap.1

What is the selectedcontent element?

<selectedcontent> is the element that displays the currently selected option’s rich content inside the select’s button. Customizable select allows a <button> as the first child of <select>, which was previously not allowed in HTML; placing <selectedcontent> inside that button mirrors the selected option’s content, such as an SVG next to its label, and the element can be styled directly.12

What happens in browsers that don’t support customizable select?

The control degrades gracefully. Progressive enhancement means the select stays fully usable and customers get the native pop-up, and because <select> is a semantic element, the built-in accessibility features remain. The session recommends testing in unsupported browsers and with assistive tools before shipping.1


Customizable select deletes a dependency the same way CSS Grid Lanes does for masonry layouts, and the pairing is deliberate: session 315 itself closes by pointing viewers to the Grid Lanes session, and the demo site uses both features together.1 Apple keeps extending what plain HTML elements can do, the same trajectory covered in the HTML model element on Apple platforms, and every drop-down library you no longer ship strengthens the case in the no-build manifesto. The full series hub is the Apple Ecosystem Series.

References


  1. Apple, WWDC 2026 session 315, Rediscover the HTML select element. Source for the before-state (heavy JavaScript libraries or lots of div elements); availability starting in Safari 27 and Chrome 135, with Safari Technology Preview and Safari Beta for early access; appearance: base-select applied on the select and on ::picker(select); the ::picker-icon and ::checkmark selectors styled via content and width; the :open pseudo-class; the pre-existing :checked selector for emphasizing the selection; arbitrary HTML inside options (images, videos, emojis) with the SVG-plus-label demo and the empty-alt screen-reader detail; the grid layout inside the drop-down via grid-template and gap; the first-child <button> replacing the built-in button (previously not allowed in HTML); the radial color picker demo; the “pull down buttons on Apple platforms” naming; and the progressive-enhancement fallback to the native pop-up. 

  2. WebKit, News from WWDC26: WebKit in Safari 27 beta. Source for the name of the <selectedcontent> element, its placement inside the select’s first-child <button>, and its behavior of displaying the currently selected option’s content while being directly stylable. 

Related Posts

CSS Grid Lanes: Native Masonry in Safari

CSS Grid Lanes brings native masonry layout to Safari 26.4 in three lines of CSS, with a flow-tolerance dial that fixes …

10 min read

The HTML <model> Element Comes to Every Apple OS

The HTML model element now renders drop-in 3D in Safari on iOS, iPadOS, and macOS with stagemode, entityTransform, baked…

11 min read

The No-Build Manifesto: Shipping Without a Bundler

FastAPI + HTMX + plain CSS with zero build tools and perfect Lighthouse scores. Real production numbers, honest tradeoff…

19 min read