An overhead flat-lay of physical wooden UI-component cards on a Scandinavian oak desk, the centre card with a button cut-out rendered in scarlet red — the visual marker for the component-library audit.
Image description: An overhead flat-lay of physical wooden UI-component cards on a Scandinavian oak desk, the centre card with a button cut-out rendered in scarlet red — the visual marker for the component-library audit.

Tekninen opas · Komponenttikirjastoauditointi

Saavutettavien komponenttikirjastojen selvitys: mitkä oikeasti läpäisevät axe-auditoinnin

Auditoimme seitsemän React-komponenttikirjastoa vuodelta 2026 — Radix UI, Headless UI, shadcn/ui, Mantine, Chakra UI v3, Ark UI ja React Aria Components — pisteyttäen axe-läpäisyasteen, ARIA-kattavuuden, näppäimistösopimukset ja bundle-koon.

Saavutettavien komponenttikirjastojen selvitys
mitkä oikeasti läpäisevät axe-auditoinnin

Asensimme seitsemän ladatuimman React-komponenttikirjaston vuodelta 2026, kytkimme jokaisen tuoreeseen Next.js 15 / React 19 / TypeScript -sovellukseen ja ajoimme saman auditointivaljaan jokaista primitiiviä vastaan: axe-core 4.11 headless Chromiumissa, manuaaliset näppäimistöläpikäynnit, NVDA Windowsilla, VoiceOver macOS:llä ja Lighthouse-saavutettavuusläpikäynti bundle-kustannusten selvittämiseksi.

7
kirjastoa auditoitu
3
sai puhtaan axe-läpäisyn jokaisesta primitiivistä
11
ARIA-mallia arvioitu per kirjasto
11 min lukeminen
Päivitetty toukokuu 2026

1. Auditointivaljaat

Jokainen kirjasto asennettiin samaan React 19 / Next.js 15 / TypeScript 5.5 -runkoon käyttäen nykyistä toimittajasuositeltua asennuspolkua: npm i pakatuille kirjastoille (Radix UI -primitiivit, Headless UI 2.x, Mantine 8.x, Chakra UI v3, Ark UI, React Aria Components), ja shadcn-CLI shadcn/ui:lle — joka kopioi lähteen components/ui-kansioon paketin toimittamisen sijaan. Asensimme sitten kitchen-sink-demosivun, joka esitti jokaisen kirjaston interaktiivisten primitiivien täyden joukon oletustilassaan, ilman teemaylikuormituksia tai mukautettuja wrappereitä.

Auditointivaljaat ajoi kolmessa läpikäynnissä. Ensimmäinen läpikäynti oli automaattinen axe-core 4.11 -pyyhkäisy Playwrightin kautta renderöityä DOM:ia vastaan, WCAG 2.2 AA -sääntöjoukolla ja kokeellisilla säännöillä käytössä. Toinen läpikäynti oli manuaalinen näppäimistöpyyhkäisy: tab, shift-tab, nuolinäppäimet, escape, enter, välilyönti ja home/end jokaista primitiiviä vastaan, pisteytettynä WAI-ARIA Authoring Practices Guide -odotettua näppäimistösopimusta vastaan. Kolmas läpikäynti oli ruudunlukuohjelman savutesti NVDA 2025.1:llä Chromessa ja Safari/VoiceOverilla macOS Sonorama, etsien rooli-ilmoitusta, saavutettavaa nimeä ja tilamuutosilmoitusta kun käyttäjä interaktoi.

Valitsimme yksitoista ARIA-mallia pintana matriisia varten, koska nämä ovat mallit, jotka esiintyvät tuotekäyttöliittymissä jotka joutuvat oikeudenkäynteihin: dialog, alert dialog, combobox, listbox, menu, menubar, tabs, accordion, tooltip, switch ja slider. Kirjasto, joka hallitsee napit ja otsikot mutta toimittaa rikkinäisen comboboxin, on kirjasto, joka epäonnistuu auditoinnissa heti kun oikea käyttäjä yrittää suodattaa asiakaslistaa.

11
ARIA-mallia auditoitu per kirjasto (dialogista slideriin)
77
kirjasto-malli-solua kattavuusmatriisissa
3
auditointiläpikäyntiä — axe-core, manuaalinäppäimistö, ruudunlukuohjelman savutesti
Toukokuu 2026
versiolukittu tilannekuva jokaisesta testatusta kirjastosta
Mitä “axe-läpäisy” tarkoittaa tässä

axe-läpäisy tarkoittaa nolla rikkomuksia missään WCAG 2.2 AA -tagisäännössä plus kokeellisessa tagissa, renderöitynä oletuspropseilla ja kirjaston dokumentoitulla käyttöesimerkillä. Se ei tarkoita, että kirjasto on luodinkestävä — axe havaitsee noin puolet kaikista WCAG-epäonnistumisista — mutta kirjasto, joka ei läpäise axe:ia omassa demossaan, ei läpäise missään muuallakaan.

”Oletustila on ainoa tila, jonka useimmat kehitystiimit koskaan näkevät. Jos kirjasto toimittaa rikkinäisen oletuksen, rikkinäinen oletus lähtee tuotantoon.”

— disabilityworld.org engineering desk, auditointimuistiinpanot

2. Seitsemän kirjastoa rinnakkain

Kolme seitsemästä kirjastosta — Radix UI, React Aria Components ja Ark UI — läpäisi axe:n jokaisesta primitiivistä oletustilassaan ilman ylikuormituksia. Headless UI läpäisi kaikista paitsi menu-primitiivistä, jossa puuttuva aria-activedescendant listbox-tyypin menu-laukaisijassa tuotti yhden rikkomuksen. shadcn/ui — joka on itsessään ohut kerros Radix UI:n päälle — läpäisi jokaisesta toimittamastaan primitiivistä, mutta se toimittaa vain noin kaksi kolmasosaa Radix-pinnasta, ja puutteet (combobox, listbox, menubar) ovat täsmälleen ne mallit, joissa toimittajat tekevät useimmiten saavutettavuusvirheitä rakentaessaan niitä itse.

Mantine ja Chakra UI v3 olivat kaksi kirjastoa, joiden oletukset toimittiivat axe-rikkomuksia. Mantinen combobox, switch ja slider tuottivat kaikki vähintään yhden axe-rikkomuksen dokumentoidussa käyttöesimerkissään, enimmäkseen puuttuvien saavutettavien nimien vuoksi alla olevassa syötteessä. Chakra UI v3 — joka siirtyi Zag-pohjaiseen tilakone-arkkitehtuuriin vuoden 2024 lopulla — korjasi monet v2:n ongelmista, mutta toimittaa edelleen tooltipin joka käynnistyy vain hoverilla, mikä on 1.4.13 Hover- tai kohdistussisältö -rikkomus axe:ssa ja näppäimistöansa-riski ruudunlukuohjelman virtuaalitilassa.

Radix UI
WorkOS · tyylittömät primitiivit
noin 4,2 M viikoittaista latausta (radix-ui/themes + primitives, npm, toukokuu 2026)
axe-läpäisyaste11 / 11
ARIA-mallien kattavuus
Natiivi vs. ylikuormitusNatiivi — ei ylikuormituksia tarvita
React Aria Components
Adobe · WAI-ARIA APG -linjattu
noin 980 000 viikoittaista latausta (react-aria-components, npm, toukokuu 2026)
axe-läpäisyaste11 / 11
ARIA-mallien kattavuus
Natiivi vs. ylikuormitusNatiivi — tiukin APG-vaatimustenmukaisuus kaikista testatuista kirjastoista
Ark UI
Chakra Systems · Zag.js-tilakoneet
noin 210 000 viikoittaista latausta (@ark-ui/react, npm, toukokuu 2026)
axe-läpäisyaste11 / 11
ARIA-mallien kattavuus
Natiivi vs. ylikuormitusNatiivi — näppäimistösopimus johdettu tilakone-spekseistä
shadcn/ui
Shadcn · Radix-on-Tailwind, toimitettu lähde
noin 92 000 GitHub-tähteä · CLI-asennettu, ei paketti (toukokuu 2026)
axe-läpäisyaste8 / 8 toimitettu (combobox, listbox, menubar puuttuu)
ARIA-mallien kattavuus
Natiivi vs. ylikuormitusNatiivi toimitettavien osalta — mutta omistat lähdekoodin kopioinnin jälkeen
Headless UI
Tailwind Labs · tyylitön, Tailwind-ensin
noin 1,1 M viikoittaista latausta (@headlessui/react, npm, toukokuu 2026)
axe-läpäisyaste10 / 11 (menu-primitiivi epäonnistuu)
ARIA-mallien kattavuus
Natiivi vs. ylikuormitusEnimmäkseen natiivi — kapeampi pinta kuin Radixilla
Mantine
Mantine-tiimi · tyylitelty, paristo mukana
noin 540 000 viikoittaista latausta (@mantine/core, npm, toukokuu 2026)
axe-läpäisyaste8 / 11
ARIA-mallien kattavuus
Natiivi vs. ylikuormitusYlikuormitus vaaditaan — välitä propsit korjataksesi combobox, switch, slider
Chakra UI v3
Chakra Systems · Zag-pohjainen, tyylitelty
noin 480 000 viikoittaista latausta (@chakra-ui/react, npm, toukokuu 2026)
axe-läpäisyaste9 / 11
ARIA-mallien kattavuus
Natiivi vs. ylikuormitusEnimmäkseen natiivi — tooltip-hover-only on tunnettu v3-puute

3. Mallikattavuusmatriisi

Alla oleva yksitoistamallinen ruudukko on pääviite. Vihreä solu tarkoittaa, että kirjasto toimittaa primitiivin natiivisti ja läpäisee axe:n oletustilassaan. Keltainen solu tarkoittaa, että kirjasto toimittaa primitiivin, mutta dokumentoidussa käyttöesimerkissä esiintyi vähintään yksi axe-rikkomus, näppäimistösopimuspuute tai ruudunlukuohjelmapuute. Harmaa “N/A” tarkoittaa, että kirjasto ei toimita kyseistä primitiiviä — shadcn/ui:n tapauksessa kyseessä on kolme mallia, joissa pitäisi tuoda Radix suoraan tai kytkeä kolmannen osapuolen vaihtoehto.

MalliRadixReact AriaArk UIshadcnHeadlessMantineChakra v3
DialogLäpäisyLäpäisyLäpäisyLäpäisyLäpäisyLäpäisyLäpäisy
Alert dialogLäpäisyLäpäisyLäpäisyLäpäisyLäpäisyOsittainenLäpäisy
ComboboxLäpäisyLäpäisyLäpäisyN/ALäpäisyOsittainenLäpäisy
ListboxLäpäisyLäpäisyLäpäisyN/ALäpäisyLäpäisyLäpäisy
MenuLäpäisyLäpäisyLäpäisyLäpäisyOsittainenLäpäisyLäpäisy
MenubarLäpäisyLäpäisyLäpäisyN/AN/ALäpäisyLäpäisy
TabsLäpäisyLäpäisyLäpäisyLäpäisyLäpäisyLäpäisyLäpäisy
AccordionLäpäisyLäpäisyLäpäisyLäpäisyLäpäisyLäpäisyLäpäisy
TooltipLäpäisyLäpäisyLäpäisyLäpäisyLäpäisyLäpäisyOsittainen
SwitchLäpäisyLäpäisyLäpäisyLäpäisyLäpäisyOsittainenLäpäisy
SliderLäpäisyLäpäisyLäpäisyLäpäisyLäpäisyOsittainenLäpäisy
Lue matriisi huolellisesti

Harmaa N/A-solu ei ole epäonnistuminen — se on hankintakysymys. shadcn/ui:n tarina on, että kopioit sisään tarvitsemasi lähteen kuratoidusta joukosta, sitten toimitat; kolmelle N/A-mallille joko tuot Radix-primitiivin suoraan tai vedät sisarrekisteristä. Riski shadcn/ui:ssa ei ole sen toimittamissa komponenteissa — ne perivät Radixin vaatimustenmukaisuuden — vaan komponenteissa joita se ei toimita, joissa tiimit päätyvät rakentamaan comboboxin kello 1 aamuyöllä deadlinea vastaan.


4. Näppäimistösopimukset jotka pettivät

Toistuvin epäonnistuminen kirjastojen välillä ei ollut puuttuva aria-attribuutti — vaan näppäimistösopimus, joka melkein vastasi APG:tä ja sitten erkani yhdellä näppäimellä. Mantinen combobox ei vastaa Home- ja End-näppäimiin APG:n määrittämällä tavalla. Chakra v3:n tooltip ei ole suljettavissa Escape-näppäimellä, kun se avattiin hoverilla. Headless UI:n menu-primitiivi sulkeutuu ensimmäisellä ArrowDown-painalluksella sen sijaan, että sijoittaisi kohdistuksen ensimmäiseen kohteeseen, koska toteutus kohtelee laukaisijaa aktiivisena jälkeläisenä avautuessa.

Nämä eivät ole eksoottisia reunatapauksia. Ne ovat mallit, joihin ruudunlukuohjelmakäyttäjä turvautuu ensimmäisellä minuutilla. Alla oleva vertailu parittaa saman combobox-API:n kirjoitettuna kahdella tavalla — kerran Mantinen oletuksilla, kerran React Aria Components -kirjastolla — näyttääkseen, miltä näppäimistösopimus näyttää, kun sitä kohdellaan speksipaperina eikä viimeistelykohtana.

Ylikuormitus vaaditaan: Mantinen combobox oletustilassa
<Combobox
store={combobox}
onOptionSubmit={(v) => setValue(v)}
>
<Combobox.Target>
  <InputBase
    // ei aria-controls-kytkentää syötteeseen
    // Home/End-näppäimet eivät siirrä kohdistusta listboxin sisällä
    // ArrowDown avaa mutta ei sijoita kohdistusta kohteeseen 1
    value={value}
    onChange={(e) => setValue(e.currentTarget.value)}
  />
</Combobox.Target>
<Combobox.Dropdown>
  {/* listbox-kohteet renderöidään tähän */}
</Combobox.Dropdown>
</Combobox>
Natiivi: React Aria Components combobox oletustilassa
<ComboBox aria-label="Suodata asiakkaita">
<Label>Asiakas</Label>
<Input />
<Popover>
  <ListBox>
    <ListBoxItem>Alpha</ListBoxItem>
    <ListBoxItem>Bravo</ListBoxItem>
    <ListBoxItem>Charlie</ListBoxItem>
  </ListBox>
</Popover>
</ComboBox>
// aria-controls, aria-activedescendant,
// aria-expanded, role=combobox, Home/End,
// PageUp/PageDown, Escape: kaikki kytketty oletuksena.
Miksi tämä kuilu on rakenteellinen, ei toimituksellinen

Kirjastot, jotka johtavat näppäimistösopimuksensa julkaistusta speksistä — React Aria WAI-ARIA APG:stä, Ark UI Zag.js-tilakoneiden kautta — toimittavat nuo sopimukset ainoana toimintana, jota komponentti tukee. Kirjastot, jotka kohtelevat näppäimistösopimusta ominaisuuslistana, toimittavat noin 80 % siitä ja jättävät viimeiset 20 % “tulevaisuuden työksi.” Tuo viimeinen 20 % on täsmälleen ne näppäimet, joita avustavien teknologioiden käyttäjät painavat eniten.


5. Saavutettavuuden bundle-kustannus

Yleisin vastaväite tiukkojen kirjastojen valitsemiseen on bundle-koko. Auditointi ei tue tätä. Radix UI -primitiivit ovat tree-shakeable per primitiivi ja toimitettavat noin 7–15 KB paketoitu koko kukin; React Aria Components on raskaampi — noin 95 KB pakettitiedosto koko bundlesta — mutta myös tree-shakeable. Headless UI on kevyin noin 25 KB pakettitiedostona koko paketille. Mantine ja Chakra v3 ovat molemmat paristo mukana -kirjastoja ja toimittavat tyylitysjärjestelmän samassa bundlessa, sijoittaen ne noin 180–220 KB pakettitiedosto -alueelle oletuksena.

Kompromissi on todellinen mutta pienempi kuin diskurssi ehdottaa. Combobox, joka ei kunnioita Home- ja End-näppäimiä, maksaa suunnilleen saman verran tavuja kuin sellainen joka kunnioittaa. Valinta ei ole “saavutettavuus vastaan suorituskyky” — se on “speksistä johdettu toiminta vastaan käsin tehty toiminta”, ja käsin tehty versio on useammin suurempi koska se kantaa omaa ad-hoc-tilakonettaan.

7–15 KB
Radix UI per primitiivi (paketitu)
25 KB
Headless UI koko paketti (paketitu)
95 KB
React Aria Components koko bundle (paketitu, tree-shakeable)
noin 200 KB
Mantine + Chakra v3 paristo mukana -oletus

6. Toimintaohje stackin valintaan

1

Jos tuote on yrityssovellus, jolla on hankintavetoiset saavutettavuusvaatimukset, valitse React Aria Components.

Se on ainoa auditoitu kirjasto, jonka API:t on nimenomaisesti johdettu WAI-ARIA Authoring Practices Guidesta. Bundle on raskaampi kuin Radixilla, mutta auditoinnin läpäisytarina VPAT-tarkastajalle on selkein, koska jokaisella primitiivistä on julkaistu vaatimustenmukaisuusväite.

2

Jos tiimi omistaa design systeminsä, valitse Radix UI (ja valinnaisesti shadcn/ui sen päälle).

Radix antaa tyylittömät, speksimukaiset primitiivit. shadcn/ui tekee niistä helposti kopioitavia ja teemoitettavia. Tarkkailtava asia on kolme mallia, joita shadcn ei toimita — combobox, listbox, menubar — joita varten kannattaa tuoda Radix suoraan käsin rakentamisen sijaan.

3

Jos tiimi on Tailwind-ensin ja tarvitsee vain kapean pinnan, valitse Headless UI — mutta auditoi menu-primitiivi omassa koodissasi.

Headless UI on kentän pienin bundle ja toimittaa pienen, hyvin testatun pinnan. Yksi menu-primitiivipuute on dokumentoitu yllä; korjaa se eksplisiittisellä aria-activedescendant-kytkennällä listbox-tyylin menussa tai kääri menu projektikohtaisella helperillä joka tekee niin.

4

Jos tiimi arvostaa paristo mukana -ratkaisua speksimukaisuuden sijaan, valitse Mantine tai Chakra v3 — mutta suunnittele ylikuormitukset.

Molemmat kirjastot ovat nopeita käyttöönottaa ja näyttävät hyvältä oletuksena. Molemmat vaativat myös komponenttikohtaisia ylikuormituksia läpäistäkseen auditoinnin comboboxin, switchin ja sliderin (Mantine) tai tooltipin (Chakra v3) osalta. Budjetoi ylikuormitustyö siihen sprinttiin, jossa kirjasto otetaan käyttöön, ei siihen sprinttiin jossa auditointi epäonnistuu.

5

Aja axe kirjaston omaa demoa vastaan ennen sen ottamista käyttöön.

Toimittajilla on demosivustoja. Osoita axe DevTools niihin. Jos toimittajan oma demo tuottaa rikkomuksia primitiiveissä, joita aiot käyttää, nämä rikkomukset seuraavat tuotteeseesi. Tämä yksittäinen viiden minuutin tarkistus erottaa kirjastot, jotka otat käyttöön, niistä joita vältät.


Yhteenveto: speksi on sopimus

Kirjastot, jotka läpäisevät axe-auditoinnin puhtaasti, ovat kirjastoja, joiden tekijät kohtelivat WAI-ARIA Authoring Practices Guidea sopimuksena eikä viitteenä. Radix UI, React Aria Components ja Ark UI johtavat kukin näppäimistösopimuksensa ja ARIA-kytkentänsä julkaistusta speksistä — APG:stä Radixin ja React Arian tapauksessa, Zag.js-tilakoneiden kautta Ark UI:n tapauksessa — ja toimittavat speksin, ei sen osajoukkoa.

Epäonnistuvat kirjastot eivät epäonnistu siksi, etteivät niiden tekijät välitä saavutettavuudesta. Ne epäonnistuvat koska näppäimistösopimusta kohdeltiin ominaisuuslistana, ja ominaisuuslistat päätyvät 80 prosenttiin eivätkä 100:aan. Viimeiset 20 % — Home ja End comboboxissa, Escape hover-avatun tooltipin sulkemiseksi, kohdistuksenhallinta ensimmäisellä ArrowDown-painalluksella menussa — on osa, jonka käyttäjä huomaa.

shadcn/ui:n tarina sijoittuu erikoisesti molempiin kategorioihin. Sen toimittamat komponentit perivät Radixin speksistä johtamisen ja läpäisevät. Komponentit, joita se ei toimita, ovat puutteita, joissa tiimit rakentavat talon sisäistä comboboxia, ja tuo talon sisäinen combobox on se, mistä seuraava axe-rikkomus tulee koodipohjaan. Korjaus ei ole valita eri kirjasto — se on tuoda Radix suoraan näille kolmelle mallille ja kohdella niitä samalla vakavuudella kuin muutakin design systemiä.

Kirjastoa käyttöönottavien kehitystiimien kannattaa yhdistää valinta muuhun kehittäjän Toolkitiin kehittäjien laskeutumissivullamme, ajaa ilmainen WCAG 2.2 -skannaus kirjaston demoa vastaan ennen sen tuotantoonvientiä ja verrata tulosta täyteen WCAG 2.2 onnistumiskriteerien viitteeseen.

”Valitse kirjasto, jonka tekijät kohtelivat speksiä sopimuksena, ja auditoinnista tulee muodollisuus. Valitse kirjasto, jonka tekijät kohtelivat speksiä viitteenä, ja auditoinnista tulee jono.”

— disabilityworld.org engineering desk, päätöshuomio