Dunfey · Hotel WWDC as data, est. 1983
Front desk everything
Years
Topics

2026 DesignSafari & Web

WWDC26 · 10 min · Design / Safari & Web

Rediscover the HTML select element

Learn how to unlock full control of styling select menus on the web. The HTML select element is getting a major upgrade with a new CSS appearance value, and new pseudo-elements. Discover how the select options can contain rich content with new possibilities in HTML. Build selects that match your design system, while keeping all the accessibility and robustness of the default element.

Watch at developer.apple.com ↗

Transcript all transcripts

Chapters

  • 0:00 — Introduction
  • 2:32 — Style the select button
  • 3:47 — Customize the drop-down
  • 5:00 — Go beyond text options
  • 6:50 — The selectedcontent element
  • 7:46 — Fallback for unsupported browsers
  • 8:49 — Next steps

Code shown on screen · 18 snippets

Basic markup xml · at 1:11 ↗
<label for="sort-select">Sort by</label>
<select id="sort-select">
    <option>Newest</option>
    <option>Oldest</option>
</select>
Native form control yaml · at 2:37 ↗
select {
 
}
appearance: base-select yaml · at 2:50 ↗
body {
    font-family: Gill Sans, sans-serif;
}

select {
    appearance: base-select;
}
Style the select button yaml · at 3:07 ↗
select {
    appearance: base-select;
    background-color: var(--green-10);
    border: none;
    padding: 0.6em 1em;
}
Picker icon yaml · at 3:08 ↗
select:open {
    background-color: var(--green-100);
    color: white;
}
Picker icon open state yaml · at 3:29 ↗
select:open {
    background-color: var(--green-100);
    color: white;
}

select:open::picker-icon {
    content: url(icons/arrow-white.svg);
}
Picker select yaml · at 4:08 ↗
::picker(select) {

}
Picker select spacing yaml · at 4:21 ↗
::picker(select) {
    appearance: base-select;
    padding: 4px;
    margin-top: 0.5em;
}
Picker select border and shadow yaml · at 4:28 ↗
::picker(select) {
    appearance: base-select;
    padding: 4px;
    margin-top: 0.5em;
    border: 1px solid rgba(0,0,0,0.2);
    border-radius: 9px;
    box-shadow: 0 4px 20px rgba(0,0,0,0.2);
}
Custom option styles yaml · at 4:36 ↗
option:checked {
    font-weight: 600;
}

option:not(:checked) {
    color: #777;
}
Picker option checkmark yaml · at 4:42 ↗
option::checkmark {
    content: url(checkmark.svg);
    width: 0.65em;
}
Images in option xml · at 5:31 ↗
<option value="flower">
    <img src="flowers.svg" alt="">
    <span class="text">Flowers</span>
</option>
Custom option highlight yaml · at 5:52 ↗
option::checkmark {
    display: none;
}

option:checked {
    background: #00857e;
    color: white;
}
Grid layout in drop downs yaml · at 6:20 ↗
::picker(select) {
    display: grid;
    grid-template: 
       1fr 1fr / 1fr 1fr 1fr;
    gap: 1rem;
}
Select with image options xml · at 6:43 ↗
<select>
    <option value="anywhere">
        <img src="icons/all.svg" alt="">
        <span class="text">Everything</span>
    </option>
    <option value="buildings">
        <img src="icons/buildings.svg" alt="">
        <span class="text">Buildings</span>
    </option>
    <option value="flowers">
        <img src="icons/flower.svg" alt="">
        <span class="text">Flowers</span>
    </option>
    
</select>
Select menu xml · at 7:11 ↗
<select>
    
    
    
    <option>    </option>
    <option>    </option>
    <option>    </option>
</select>
Select menu button xml · at 7:13 ↗
<select>
    <button>
    
    </button>
    <option>    </option>
    <option>    </option>
    <option>    </option>
</select>
SelectedContent Element xml · at 7:29 ↗
<select>
    <button>
        <selectedcontent></selectedcontent>
    </button>
    <option>     </option>
    <option>     </option>
    <option>     </option>
</select>

Resources