← Wszystkie wpisy

Customizable select: nareszcie stylizacja prawdziwego elementu <select>

Wyjście poza domyślny element select oznaczało dotąd jeden z dwóch złych kompromisów: ciężkie biblioteki JavaScript albo mnóstwo elementów div, przy czym w obu przypadkach dostępność stawała się problematyczna.1 Na WWDC 2026 zespół Safari pokazał drogę wyjścia: customizable select, czyli zestaw rozszerzeń HTML i CSS, które sprawiają, że istniejący wcześniej element <select> daje się w pełni stylizować, zachowując przy tym semantykę, nawigację klawiaturą i obsługę czytników ekranu, które już oferuje. Począwszy od Safari 27 i Chrome 135 można na nowo ostylować przycisk, rozwijane menu, znacznik wyboru, a nawet strzałkę, a następnie umieścić w opcjach obrazy, filmy lub emoji.1

TL;DR

  • Customizable select stylizuje prawdziwy element <select> wyłącznie za pomocą HTML i CSS, zastępując biblioteki JavaScript i stosy elementów div, po które programiści sięgali wcześniej. Dostępność zaczyna się w Safari 27 i Chrome 135.1
  • Aktywacja to appearance: base-select, stosowane dwukrotnie: raz na samym elemencie select, aby odblokować stylizację przycisku, i raz na ::picker(select), aby zrezygnować z natywnego rozwijanego menu.1
  • Wraz z tym pojawiają się nowe, dające się stylizować części: ::picker-icon zmienia wygląd strzałki za pomocą właściwości content oraz width, ::checkmark na elemencie option wymienia znacznik wyboru w ten sam sposób, a pseudoklasa :open stylizuje przycisk, gdy menu jest otwarte.1
  • Opcje przyjmują dowolny rodzaj treści: obrazy, filmy, emoji. Demo z sesji umieszcza w każdej opcji element SVG oraz etykietę, a następnie układa całe rozwijane menu jako siatkę CSS przy użyciu grid-template i gap.1
  • Umieszczenie elementu <button> jako pierwszego dziecka <select>, wcześniej niedozwolone w HTML, zastępuje wbudowany przycisk; element <selectedcontent> znajdujący się wewnątrz niego wyświetla bogatą treść wybranej opcji.2
  • Progresywne ulepszanie pojawia się bez dodatkowego kosztu: przeglądarki bez obsługi wracają do natywnego okienka pop-up, a semantyczny element select wszędzie zachowuje swoją wbudowaną dostępność.1

Od zupy z elementów div z powrotem do semantycznego HTML

Watch on Apple Developer ↗

Tim, inżynier Safari, stosuje appearance: base-select do demonstracyjnego portfolio fotografa, zaczynając od 2:48.

Punktem wyjścia w sesji jest to, co <select> już robi dobrze. Element zapewnia podstawową dostępność od ręki: nawigację klawiaturą po elementach option oraz solidne zachowanie z czytnikami ekranu, a wszystko to bez zewnętrznych bibliotek.1 Na platformach Apple natywne renderowanie to dobrze znany przycisk rozwijany i pasuje on do każdej innej kontrolki na platformie, co daje użytkownikom znany sposób poruszania się po nim.1

Pułapką zawsze był design. Wystarczy umieścić natywną kontrolkę na ostylowanej stronie, a od razu wygląda nie na miejscu; nie chce się wtopić w otoczenie. Do tej pory rozwiązaniem było całkowite porzucenie tego elementu na rzecz widżetu JavaScript lub stosu elementów div i ręczne odbudowanie dostępności. Customizable select zachowuje element i oddaje w ręce stylizację, w trzech etapach, które sesja omawia na prawdziwym projekcie portfolio fotografa: przycisk, rozwijane menu i wreszcie treść wykraczająca poza zwykły tekst.1

Stylizacja przycisku: base-select, ::picker-icon i :open

Przycisk to ta część elementu select, którą się klika, aby pokazać menu, a pierwszym krokiem jest pojedyncza deklaracja:

select {
  appearance: base-select;
}

appearance: base-select zamienia natywne renderowanie na mniejszy zestaw bazowych stylów, które można zmieniać.1 Efekt pojawia się natychmiast dzięki dziedziczeniu: demonstracyjna strona ustawia font-family: Gill Sans na elemencie body, a przycisk select dziedziczy teraz czcionkę z body, dopasowując się do etykiety obok.1 Stamtąd tło, obramowanie i wypełnienie dostosowuje się jak w każdym innym elemencie.

Dwa nowe punkty zaczepienia dopełniają przycisk. Strzałka ma własny selektor, ::picker-icon, który przyjmuje właściwość content na zastępczy znak oraz width, aby ustalić jego rozmiar. Pseudoklasa :open stylizuje przycisk inaczej, gdy rozwijane menu jest otwarte:

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 */
}

Werdykt sesji na temat efektu: select pasujący do reszty strony w zaledwie kilku wierszach CSS.1

Stylizacja rozwijanego menu: ::picker(select) i ::checkmark

Menu ma własne części, które można stylizować. Do samego rozwijanego menu odwołujemy się przez ::picker(select) na elemencie select, a do znacznika wyboru przez ::checkmark na elemencie option.1 Rezygnacja z natywnego menu wymaga appearance: base-select po raz drugi, teraz na pickerze:

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);
}

Mając czystą kartę, demo rozmieszcza odstępy za pomocą padding i margin, a następnie zajmuje się obramowaniami i cieniem box-shadow rozwijanego menu.1 Do podkreślenia bieżącego wyboru służy istniejący wcześniej selektor :checked, a nie coś nowego: pogrub wybraną opcję, wyszarz pozostałe.1

option:checked {
  font-weight: bold;
}

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

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

::checkmark działa dokładnie tak jak ::picker-icon: ustaw content oraz width, a domyślny znacznik wyboru zamienia się w dowolny znak pasujący do projektu.1

Bogata treść w opcjach, ułożona jako siatka

Większa zmiana dotyczy tego, co znajduje się wewnątrz <option>. Sesja mówi to wprost: działa dowolny rodzaj treści, obrazy, filmy, emoji, cokolwiek się chce.1 Demo buduje przeglądarkę kategorii dla najpopularniejszych tematów fotografa, z symbolem SVG i etykietą wewnątrz każdej opcji:

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

Zwróć uwagę na pusty atrybut alt. Tim celowo zostawia tekst alternatywny obrazu pusty, ponieważ etykieta „Flowers” zostałaby w przeciwnym razie odczytana przez czytniki ekranu dwukrotnie.1 Drobny szczegół, realna konsekwencja: bogate opcje pozostają tak samo użyteczne z technologiami wspomagającymi jak te zwykłe.

Po usunięciu domyślnego znacznika wyboru demo wyróżnia wybraną opcję za pomocą selektora checked i zmian koloru.1 Pozostaje jeden problem: opcje złożone z symbolu i etykiety sprawiają, że rozwijane menu robi się bardzo długie. Rozwiązanie ponownie wykorzystuje już istniejący CSS, ponieważ picker jest teraz zwykłym celem stylizacji. Układ siatki przekształca całe menu:

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

grid-template definiuje liczbę wierszy i kolumn, a gap definiuje odstępy między komórkami siatki, dzięki czemu rozwijane menu układa się w uporządkowaną siatkę kategorii.1 Sesja kończy się efektowną wariacją na ten sam temat: kołowym selektorem kolorów zbudowanym w całości za pomocą customizable select.1

Wymienny przycisk i selectedcontent

W przeglądarce kategorii pozostaje jedna luka: symbole SVG żyją w opcjach, lecz przycisk pokazujący bieżący wybór wyświetla wyłącznie tekst.1 Customizable select zamyka tę lukę, pozwalając zastąpić wbudowany przycisk poprzez umieszczenie elementu <button> jako pierwszego dziecka <select>. Umieszczenie przycisku wewnątrz elementu select było wcześniej niedozwolone w HTML; teraz przyjmuje on niestandardową treść, taką jak etykiety, albo element stworzony dokładnie do tego zadania.1

Ogłoszenie wersji beta Safari 27 od WebKit podaje nazwę tego elementu: <selectedcontent>. Umieszczony w przycisku będącym pierwszym dzieckiem elementu select, wyświetla on treść aktualnie wybranej opcji i można go stylizować bezpośrednio.2

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

Element odzwierciedla dowolną bogatą treść należącą do wybranej opcji, jak SVG obok etykiety „Everything” w demie, dzięki czemu przycisk wreszcie pokazuje ten sam język wizualny co menu, które otwiera.12

Progresywne ulepszanie jest wbudowane

Ostatnim krokiem w sesji jest ten, który zespoły pomijają na własne ryzyko: sprawdzenie projektu w przeglądarkach, które nie obsługują customizable select. Odpowiedź jest najlepszego rodzaju nudna. Wkracza progresywne ulepszanie, kontrolka pozostaje użyteczna, a klienci dostają natywne okienko pop-up.1 Ponowne wykorzystanie elementu select oznacza, że scenariusz awaryjny już istnieje, a ponieważ <select> jest elementem semantycznym, wbudowane funkcje dostępności przetrwają w każdej przeglądarce.1

Dostępność jest konkretna: Safari 27 i Chrome 135. Aby wypróbować te funkcje już teraz, należy pobrać Safari Technology Preview lub Safari Beta.1 Końcowa wskazówka z sesji jest praktyczna: sprawdź demo na webkit.org, ostyluj coś prostego na własnej stronie, przetestuj w przeglądarkach bez obsługi oraz z narzędziami wspomagającymi, a także zapoznaj się z materiałami WebKit o najlepszych praktykach, aby interfejs działał dla każdego.1

Co zespół Safari dodał w labach

Kilka rzeczy z labów WWDC dopełnia obraz, zwłaszcza w kwestii tego, dokąd zmierza customizable select.

Punktem mapy drogowej, na który warto zwrócić uwagę, jest appearance: base, ta sama aktywacja uogólniona na wszystkie kontrolki formularzy, a nie tylko <select>. Wartość ta istnieje w specyfikacji CSS, lecz nigdzie jeszcze nie trafiła do wdrożenia.3 W labie panel powiedział, że „nie wchodzi teraz” i pojawi się później, a dyskusja nad specyfikacją wciąż pozostaje otwarcie nierozstrzygnięta, paneliści na żywo nie zgadzali się co do tego, jak w ogóle powinna wyglądać nieostylowana baza.4 Deklarowane cele projektowe są wystarczająco jasne: dziedziczyć maksymalnie ze stylów strony, bez magii układu oraz identyczne renderowanie bazowe i identyczna struktura DOM w różnych silnikach.4

Historia wyjaśnia, dlaczego customizable select w ogóle wykorzystuje ponownie <select>. Pierwotną propozycją był zupełnie nowy element <selectmenu>. Inżynier standardów WebKit zabiegał o ponowne wykorzystanie <select>, aby przeglądarki bez obsługi za darmo zachowały natywny scenariusz awaryjny, co jest dokładnie tą historią progresywnego ulepszania opisaną powyżej.4

Z panelu wyłoniła się jedna twarda zasada: zawsze zachowuj treść tekstową w swoich opcjach. Opcje zawierające wyłącznie ikony renderują puste natywne okienko pop-up w przeglądarkach bez obsługi, co pozostawia użytkowników na lodzie na silnikach bez wsparcia.4

Najważniejsze wnioski

Dla programistów frontendu: - Aktywuj funkcję za pomocą appearance: base-select na elemencie select dla przycisku oraz ponownie na ::picker(select) dla rozwijanego menu; następnie stylizuj tło, obramowanie, wypełnienie, odstępy i box-shadow jak w każdym innym elemencie.1 - Wymień strzałkę za pomocą ::picker-icon, a znacznik wyboru za pomocą ::checkmark, oba przez content plus width; ostyluj stan otwarcia za pomocą :open; podkreśl wybór istniejącym wcześniej selektorem :checked.1 - Umieść prawdziwy kod HTML wewnątrz <option> (obrazy, filmy, emoji) i przekształć menu za pomocą istniejącego CSS, jak siatka grid-template plus gap; zastąp wbudowany przycisk elementem <button> będącym pierwszym dzieckiem i zawierającym <selectedcontent>.12

Dla zespołów dbających o dostępność: - Semantyczny select zachowuje nawigację klawiaturą i obsługę czytników ekranu bez zewnętrznych bibliotek, zarówno w obsługiwanych, jak i nieobsługiwanych przeglądarkach.1 - Gdy opcje niosą zarówno obraz, jak i etykietę tekstową, należy pozostawić tekst alternatywny obrazu pusty, aby czytniki ekranu nie odczytywały etykiety dwukrotnie.1 - Przed wdrożeniem przetestuj w przeglądarkach bez obsługi oraz z narzędziami wspomagającymi, zgodnie z listą kontrolną z samej sesji.1

Dla liderów technicznych planujących wdrożenie: - Traktuj customizable select jako progresywne ulepszanie: Safari 27 i Chrome 135 otrzymują niestandardowy projekt, wszyscy pozostali dostają natywne okienko pop-up i nie jest wymagany żaden scenariusz awaryjny w JavaScript.1 - Oceń tę funkcję już teraz w Safari Technology Preview lub Safari Beta i zważ ją wobec biblioteki rozwijanego menu obecnie zalegającej w Twoim pakiecie.1

FAQ

Czym jest customizable select?

Customizable select to zestaw możliwości HTML i CSS, wprowadzony przez zespół Safari na WWDC 2026 i zaczynający się w Safari 27 oraz Chrome 135, który sprawia, że istniejący wcześniej element <select> staje się w pełni konfigurowalny. Przycisk, rozwijane menu, strzałkę i znacznik wyboru stylizuje się za pomocą CSS, a w opcjach umieszcza bogatą treść, zachowując przy tym wbudowaną dostępność elementu.1

Jak aktywować customizable select?

Należy zastosować appearance: base-select w dwóch miejscach: na samym elemencie select, co zastępuje natywne renderowanie przycisku mniejszym zestawem bazowych stylów, oraz na ::picker(select), co sprawia, że rozwijane menu rezygnuje z natywnego renderowania, dzięki czemu można je swobodnie stylizować.1

Czy mogę umieścić obrazy lub inny kod HTML wewnątrz elementów option?

Tak. Sesja stwierdza, że wewnątrz opcji można umieścić dowolny rodzaj treści: obrazy, filmy, emoji. Demo wykorzystuje SVG i etykietę tekstową na każdą opcję, z pustym tekstem alternatywnym obrazu, aby czytniki ekranu odczytywały etykietę tylko raz, i układa menu jako siatkę CSS przy użyciu grid-template i gap.1

Czym jest element selectedcontent?

<selectedcontent> to element, który wyświetla bogatą treść aktualnie wybranej opcji wewnątrz przycisku elementu select. Customizable select pozwala na umieszczenie <button> jako pierwszego dziecka <select>, co wcześniej było niedozwolone w HTML; umieszczenie <selectedcontent> wewnątrz tego przycisku odzwierciedla treść wybranej opcji, taką jak SVG obok etykiety, a sam element można stylizować bezpośrednio.12

Co dzieje się w przeglądarkach, które nie obsługują customizable select?

Kontrolka degraduje się łagodnie. Progresywne ulepszanie oznacza, że select pozostaje w pełni użyteczny, a klienci dostają natywne okienko pop-up, a ponieważ <select> jest elementem semantycznym, wbudowane funkcje dostępności pozostają. Sesja zaleca przetestowanie w nieobsługiwanych przeglądarkach oraz z narzędziami wspomagającymi przed wdrożeniem.1


Customizable select usuwa zależność w ten sam sposób, w jaki CSS Grid Lanes robi to dla układów masonry, a to zestawienie jest celowe: sama sesja 315 kończy się skierowaniem widzów do sesji Grid Lanes, a strona demonstracyjna używa obu funkcji razem.1 Apple wciąż rozszerza możliwości zwykłych elementów HTML, tym samym torem, który omawia the HTML model element on Apple platforms, a każda biblioteka rozwijanego menu, której już nie dostarczasz, wzmacnia argumentację z the no-build manifesto. Pełnym centrum serii jest 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. 

  3. MDN Web Docs, appearance. Source for the appearance: base spec value. 

  4. Paraphrased from a locally transcribed recording of the WWDC 2026 Safari & Web Technologies Group Lab; official captions were partial. Apple, WWDC 2026, Safari & Web Technologies Group Lab. Source for the appearance: base roadmap statements (“not shipping now,” later, spec discussion still unsettled with live disagreement over the unstyled base) and its stated design goals (inherit maximally from page styles, no layout magic, identical base rendering and identical DOM structure across engines); the history that the original proposal was a new <selectmenu> element before a WebKit standards engineer pushed to reuse <select> so unsupporting browsers keep the native fallback; and the rule that options must keep text content because icon-only options render a blank native pop-up in browsers without support. 

Powiązane artykuły

Dlaczego Safari 27 wprowadza 525 poprawek: notatki z laboratorium WebKit

Laboratorium Safari na WWDC 2026 o tym, jak WebKit decyduje, co budować: 525 poprawek, przepisany loader modułów dla top…

8 min czytania

CSS Grid Lanes: natywny układ masonry w Safari

CSS Grid Lanes wnosi natywny układ masonry do Safari 26.4 w trzech liniach CSS, a regulator `flow-tolerance` rozwiązuje …

8 min czytania

Manifest bez bundlera: produkcja bez narzędzi budowania

FastAPI + HTMX + czysty CSS bez żadnych narzędzi budowania i perfekcyjne wyniki Lighthouse. Prawdziwe dane produkcyjne, …

8 min czytania