17 juni 2026
Multiselect polyfill

Wat als ik je zou vertellen dat je gewoon een ‘select’ met het ‘multiple’-attribuut kunt gebruiken, zonder compatibiliteits- of gebruiksproblemen? Dat zou fantastisch zijn, toch? Daarom heb ik een polyfill gemaakt voor native multiselects.

Het maakt gebruik van de standaard multiselect op mobiele apparaten en een aangepaste multiselect op desktops. Het verzenden en valideren van gegevens werkt zoals je verwacht, en de toegankelijkheid is gebaseerd op die van standaard form-elementen in plaats van een stapel handgeschreven ARIA-regels. Het gebruik ervan ziet er als volgt uit:

<label>Multiselect 1</label>
<select multiple required>
    <option>Option 1</option>
    <option>Option 2</option>
    <option>Option 3</option>
    <option>Option 4</option>
</select>

<script src="multiselect.js"></script>
<link rel="stylesheet" href="multiselect.css" />

Bekijk de demo en de broncode

De styling is tot een minimum beperkt, maar bevat wel een aangepast pijltje bij de selectievelden. Het ‘required’-attribuut activeert nog steeds de native client-side formuliervalidatie en het component ondersteunt het geavanceerde ‘optgroup’-element. Op mobiele apparaten staat er een kleine ‘plus’ naast het label om over te schakelen naar de desktopversie van de multiselect, voor het geval de mobiele detectie een vals positief resultaat oplevert.

Hieronder vind je een beschrijving van de voordelen:

Je schrijft standaard HTML.

Er is geen component-API, geen configuratieobject en geen framework-binding om te onthouden. Je voegt een select-element toe, koppelt een script en een stylesheet, en klaar is Kees. Omdat het een bestaand formulierelement verbetert in plaats van vervangt, werkt het identiek, of je nu server-rendered PHP, een statische website of een complexe single-page applicatie gebruikt. De markup is hetzelfde en je mentale model blijft hetzelfde.

Toegankelijkheid is gebaseerd op de oorspronkelijke semantiek.

Dit is waar de aanpak zijn nut bewijst. Omdat de component de bestaande formulierbesturingselementen uitbreidt, komen de uitvoer van de schermlezer en de toetsenbordnavigatie grotendeels van de browser en het besturingssysteem, en niet van ARIA dat je moet schrijven, testen en verdedigen tijdens een audit. Op mobiele apparaten geef je gebruikers de kiezer die al op hun telefoon aanwezig is.

Dat gezegd hebbende, is “native” niet hetzelfde als “gegarandeerd toegankelijk” — de native <select multiple> -component is met name een besturingselement met bekende problemen bij schermlezers en touchbediening. Beschouw dit dus als een patroon dat nader onderzoek verdient, niet als een opgelost probleem. Ik zou graag praktijktests met VoiceOver/iOS, TalkBack, NVDA en JAWS ontvangen, en ik zal de bevindingen publiceren — inclusief de tekortkomingen — in plaats van te beweren dat het perfect is.

Native validatie

Markeer het veld als verplicht en het werkt gewoon: de browser blokkeert de verzending totdat er iets is gekozen, zowel op mobiele apparaten als op desktops. Je krijgt native, gelokaliseerde validatieberichten zonder ook maar één regel code voor foutafhandeling te hoeven schrijven of onderhouden.

Inzendingen zoals elk ander veld

De selectievakjes op het bureaublad zijn slechts een controller; ze hebben geen eigen naam. Ze veranderen de geselecteerde status van de daadwerkelijke opties, waardoor de waarden op uw server aankomen onder de eigen naam van het selectievakje, precies zoals een normaal formulier dat zou doen. Geen verborgen invoervelden om te synchroniseren, geen speciale parsing, geen wijzigingen in uw FormData-afhandeling of uw bestaande eindpunten. Voeg het toe aan een formulier dat al werkt en dat formulier blijft gewoon werken.

Geeft op elk apparaat hetzelfde weer.

Op mobiele apparaten wordt “3 geselecteerd” weergegeven — net als in Chrome op Android, maar de weergave wordt door de component zelf aangepast, waardoor Safari en Firefox op iOS ook overeenkomen: één gedrag in plaats van drie. De fallback kan worden vertaald door data-summary="{n} geselecteerd" toe te voegen. Laat dit weg voor de Engelse standaardweergave. In moderne mobiele browsers die appearance: base-select ondersteunen, wordt de native selectie weergegeven (met size=1), ervan uitgaande dat deze mobiele browsers de samenvatting zelf in uw voorkeurstaal weergeven.

Ondersteuning voor de donkere modus

Het component volgt automatisch de voorkeur van de bezoeker voor een lichte of donkere achtergrond. De reden dat het toevoegen ervan zo eenvoudig was, is dezelfde reden dat alles hier ook zo makkelijk is: native controls weten al hoe ze zichzelf van kleur moeten veranderen. Je hoeft geen aparte stylesheet voor een donkere achtergrond te schrijven, je hoeft geen thema-variabele bij te houden en je hoeft niet elke regel achter een mediaquery te dupliceren. Je maakt simpelweg gebruik van de kracht van native HTML en CSS.

De juiste gebruikersinterface voor elk apparaat

Touchscreens krijgen de standaard keuzelijst; gebruikers met muis en toetsenbord krijgen een overzichtelijke lijst met selectievakjes. En voor de lastige tussengevallen – een touchscreen-laptop, een iPad met trackpad – is er een klein + knopje naast het label waarmee de gebruiker zelf kan overschakelen naar de versie met selectievakjes.

Het is toekomstbestendig.

Browsers maken het native select-element eindelijk aanpasbaar qua stijl (appearance: base-select), en de variant voor meerdere selecties is in aantocht. Zodra deze overal beschikbaar is, wordt deze polyfill iets dat je eenvoudig kunt verwijderen — je gewone select[multiple] blijft precies zoals het is geschreven. Dat is progressieve verbetering: geen vendor lock-in, geen herschrijving, geen technische schuld.

Klein maar fijn, en goedgekeurd voor gebruik door mensen.

Geen build-stappen, geen afhankelijkheden, niets dat je bundel onnodig groot maakt — en het is uitgebracht onder de WTFPL-licentie, dus je kunt het kopiëren, plakken en verzenden zonder juridische problemen. Het gebruik ervan ziet er zo uit, en dat is alles:

<label>Multiselect 1</label>
<select multiple required>
    <option>Option 1</option>
    <option>Option 2</option>
    <option>Option 3</option>
    <option>Option 4</option>
</select>

<script src="multiselect.js"></script>
<link rel="stylesheet" href="multiselect.css" />

Bekijk de demo en de broncode

()  Joost van der Schee