Verzoek om feedback van ontwikkelaars: aanpasbare selectie

Het stylen van formulierbesturingselementen zoals het element <select> wordt al jaren gemeld als een van de grootste knelpunten voor ontwikkelaars. We werken aan een oplossing. Dit is een complex proces en het heeft lang geduurd om het goed te krijgen, maar we zijn er bijna. Een aanpasbare versie van het select-element bevindt zich officieel in fase 2 in de WHATWG, met sterke interesse in meerdere browsers en een prototype dat je kunt testen vanaf Chrome Canary 130.

Probeer het uit en geef ons je feedback

Controleer of je installatie van Chrome Canary is geüpdatet naar versie 130 en of de experimentele functieflag voor webplatformfuncties aanstaat. Je kunt deze flag aanzetten door naar chrome://flags te gaan in de adresbalk en #experimental-web-platform-features aan te zetten. Daarna kun je de Codepen-demo's in deze post bekijken. Je kunt ook deze Codepen-verzameling bekijken om ze allemaal op één plek te vinden.

Gebruik dit formulier om feedback te geven over de functie. Het duurt maar 3 minuten om de enquête in te vullen.

Laten we de functies van de aanpasbare selectie-API doornemen, die is gebaseerd op de bestaande HTML-selectietag.

Aanmelden voor de nieuwe <select>

Als je je wilt aanmelden voor het nieuwe gedrag, gebruik je de CSS-property appearance op zowel de in-page selectieknop als de selectiekiezer. Als u zich wilt aanmelden, stelt u appearance: base-select in voor uw <select>-element en voor de ::picker(select).

::picker(select) is een nieuw pseudoelement dat door de user-agent wordt geleverd en alleen van toepassing is op <select>-elementen die zijn aangemeld voor het nieuwe gedrag met appearance: base-select. Dit pseudoelement voor de kiezer is de popover die wordt geactiveerd door de basisselectieknop. U kunt zich voor beide aanmelden, zoals in de volgende code:

select,
::picker(select) {
  appearance: base-select;
}

Je kunt ervoor kiezen alleen de knop op de pagina aan te zetten, maar je kunt niet alleen de kiezer-popover aanzetten zonder de knop op de pagina aan te zetten. ::picker(select) wordt pas gemaakt nadat appearance: base-select is toegepast op de <select>.

Nu kunt u het selectie-element aanpassen. De nieuwe aanpasbare selectie heeft een aantal standaardstijlen die er hetzelfde uitzien in verschillende browsers en besturingssystemen. Zo ziet de standaard aangepaste selectie eruit in vergelijking met de bestaande selectie in Chrome op macOS:

Standaard user-agentstijl voor aanpasbare selectie aan de rechterkant. Dit kan veranderen en we horen graag je feedback hierover.
Demo van een basisselectie versus een aanpasbare selectie.

De onderdelen ontleden

Diagram met delen van een selectie.

Zodra je in de nieuwe aanpasbare selectiemodus bent, heb je toegang tot de volgende nieuwe elementen: - selectedoption: weerspiegelt de innerHTML van de optie die op dat moment is geselecteerd. - option::before: bevat een vinkje om de geselecteerde optie aan te geven als standaard toegankelijkheidsvoorziening (dit kan worden gewijzigd). ::picker(select): pop-over die alle content buiten de button bevat in een aanpasbare selectie.

Je kunt elk deel van de selectie opmaken. Je kunt bijvoorbeeld willekeurige niet-interactieve content toevoegen binnen de <option>-elementen, de knop op de pagina opmaken waarmee het dropdownmenu wordt geopend en de dropdownlijst met opties (de ::picker(select)) opmaken.

Je kunt ook de button en de pijlindicator aanpassen en willekeurige content toevoegen binnen en rond de elementen. Je kunt niet alleen content toevoegen, maar ook deze nieuwe elementen en standaardstijlen verbergen. Als u bijvoorbeeld geen vinkje wilt in het pseudo-element ::before van de optie, gebruikt u de volgende CSS.

/* Remove the default checkmark from the selected option */
option::before {
 display: none;
}

Hoewel er een onbeperkt aantal elementen in je selectie kan staan, plaatst de browser alles buiten een <button>-element in het pseudo-element ::picker(select), dat zich gedraagt als een popover die is verankerd aan de knop. Deze <button> zet de ::picker(select) aan of uit. Opties en andere elementen die zich rechtstreeks in de selectie bevinden, worden in de ::picker(select) geplaatst. Je kunt ook je eigen wrapper gebruiken voor stijltoepassingen. Deze wrapper wordt ook in het pseudoelement ::picker(select) geplaatst.

<select>
  <button>
    <selectedoption></selectedoption>
  </button>
  // Everything else that will go into the ::picker(select) popover
</select>

De nieuwe aanpasbare <select> gebruikt functionaliteit van pop-over en ankerpositionering. De functie is gebouwd met deze 2 onderliggende technologieën. Dit betekent dat de dropdownoptielijst binnen een selectie fungeert als een pop-over die is verankerd aan de activeringsknop waarmee de selectie wordt geopend.

Je kunt ankerpositionering gebruiken om deze ::picker(select)-popover op te maken (en deze aan andere elementen te verankeren). Dit contentmodel betekent ook dat animatiestijlen voor de bovenste laag werken met de optielijst om effecten voor openen en sluiten te animeren.

Het bestaande element <select> verbeteren

Eerder werkte het Chrome-team aan het idee van een <selectlist>-element. In deze post beschrijven we hoe we deze functie hebben herontworpen om het bestaande <select>-element te hergebruiken.

Een van de belangrijkste voordelen van het hergebruik van het bestaande <select>-element is de mogelijkheid om het eenvoudige HTML-element geleidelijk te verbeteren. In vergelijking met een gloednieuw element levert hergebruik van <select> nog steeds betekenisvolle content op je pagina op. In het volgende voorbeeld zie je de aangepaste selectie versus wat een gebruiker in een niet-ondersteunde browser ziet:

Alle tekstcontent binnen de option wordt weergegeven in de reserveversie van het selectie-element.

Basisstijl

Wijzigingen kunnen zo eenvoudig zijn als de visuele stijl van het selectie-element. Bijvoorbeeld om de knopstijlen, de stijlen voor de muisaanwijzer en focus of de achtergrond van de selectieopties te updaten. Nadat je je hebt aangemeld met appearance: base-select, pas je de gewenste CSS toe op de delen van je selectie.

De stijlen van verschillende delen van de selectie wijzigen met de standaardknop.

Als je de pijlindicator wilt aanpassen, voeg je je eigen knop en pijl toe aan de selectie.

<select>
  <button>
    <selectedoption></selectedoption>
    <span>
      // Arrow here
    </span>
  </button>
  // Everything else that will go into the ::picker(select) popover
</select>

Maak de pijl daarna op:

/* style the arrow */
button span {
  /* arrow styles */
  transition: rotate 0.2s;
}

/* adjust arrow styles when the picker is open */
select:open button span {
  rotate: -180deg;
}

Complexe content binnen opties

Ga nog een stap verder en voeg content toe en pas de stijl aan buiten de tekenreeksen in de <option>-elementen in <select>. Een eenvoudig voorbeeld is het toevoegen van vlagafbeeldingen naast landnamen in een dropdownmenu. Voeg hiervoor een afbeeldingselement toe naast de optietekst.

<option value="france">
  <img src="img/flag_of_france.svg" alt="" />
  <span>France</span>
</option>
Landkiezer met vlaggen.

Een complexer voorbeeld kan profielfoto's, namen en alternatieve informatie bevatten om je te helpen beslissingen te nemen over welk item je wilt selecteren in het dropdownmenu.

<option value="eur">
    <img src="euro-flag.png" alt="" />
    <div class="currency">
      <div class="currency-short">EUR</div>
      <div class="currency-long">Euro</div>
    </div>
    <div class="symbol" aria-hidden="true">€</div>
</option>
Screenshot van de valutakiezer.

De geselecteerde optie opmaken

Misschien wil je dat de geselecteerde optie anders wordt weergegeven in de geselecteerde status dan in het dropdownmenu. Een voorbeeld hiervan is de UI van Gmail, waar het label wordt verwijderd zodra de optie is geselecteerd om ruimte te besparen. Doe dit door het element <selectedoption> te gebruiken voor de stijl. De <option> bevat alle volgende opmaak:

 <option value="reply-all">
    <img class="material-symbol"  src="material-symbol-reply.png">
    <span class="text">Reply all</span>
  </option>

Pas nu display: none toe op .text in <selectedoption>' om de tekstcontent te verbergen en alleen het icoon te tonen:

selectedoption .text {
  display: none;
}
Gmail-achtige selectie met een icoon dat de geselecteerde optie vertegenwoordigt.

Interactieve opties

Met volledige controle over de stijl van de ::picker(select), bouw je voort op de vorige demo om deze interactief te maken bij aanwijzen en focus. In deze demo wordt de nieuwe functie calc-size() gebruikt om de breedte van de kiezer te animeren van de iconen naar de volledige breedte van de opties als je de muisaanwijzer erop plaatst of als de selectie een optie heeft met focus-visible.

/* base styles when picker is open but not interacted with */
::picker(select) {
  width: var(--icon-width);
  transition: width 0.5s;
}

/* animate the text in on hover & focus */
::picker(select):hover,
select:has(option:focus-visible)::picker(select) {
  /*  auto width!  */
  width: calc-size(auto, size + 0.5rem);
}
Interactieve selectie in Gmail-stijl met geleidelijk getoonde content bij aanwijzen of focus.

Beperkingen en opmerkingen over toegankelijkheid

Grote macht brengt grote verantwoordelijkheid met zich mee. De functie heeft een aantal beperkingen om alles toegankelijk te houden.

  • Behalve <option>-elementen zijn er nog geen interactieve (focusbare) elementen toegestaan in de <select>, zoals knoppen of andere elementen. Voorlopig staat het voorgestelde contentmodel alleen de elementen <div>, <span>, <option>, <optgroup>, <img>, <svg> en <hr> toe.
  • Gesplitste knoppen bevinden zich op dit moment in de experimentfase terwijl we aan een toegankelijke oplossing werken.

In de toekomst wordt het contentmodel naar verwachting uitgebreid om flexibeler te zijn, naarmate het toegankelijkheidsverhaal voor deze functionaliteit wordt uitgewerkt.

Conclusie

We zijn blij dat deze functie zich verder ontwikkelt via werkgroepen en normalisatie-instanties. We delen onze voortgang terwijl we het prototype actief ontwikkelen en de vorm van deze functie evalueren. Laat het ons weten als iets niet werkt zoals je verwacht.

Deze functie is nog in ontwikkeling, dus we horen graag je feedback via dit korte feedbackformulier.

Bedankt dat je ons helpt om dit goed te doen en het makkelijker te maken om toegankelijke, aanpasbare formulieropties op internet te maken.