Neljä insinöörityökäytäntöä, jotka todella vaikuttavat
Kannanotto. Ei tyhjentävä. Mallit, jotka seurattuna poistavat suurimman osan saavutettavuusregressioista ennen koodikatselmointia.
Semanttinen HTML ensin, ARIA toiseksi
Kun natiivi HTML hoitaa tehtävän, käytä sitä. <button>-elementissä
on sisäänrakennettu näppäimistökäsittely, kohdistus, rooli ja Enter/Space-aktivointi;
<label> sitoo ohjauselementin kuvaukseensa;
<dialog> toimitetaan kohdistusloukulla ja sivun-muu-osa-inert
-käyttäytymisellä, jotka muuten pitäisi toteuttaa käsin;
<details> on paljastuswidget ilman JavaScriptiä lainkaan. ARIA on
poistumistie — hyödyllinen silloin, kun sopivaa natiivielementtiä ei ole, haitallinen
lisättäessä jo toimivan päälle. Viite:
WCAG 2.2 -onnistumiskriteerit ja
W3C ARIA -tekijäkäytäntöopas.
Näppäimistötuki ei ole ruksittava kohta
Jokaisen interaktiivisen elementin on toimittava pelkällä näppäimistöllä. Tab
ja Shift+Tab siirtymiseen; Enter tai Space aktivointiin; Esc ohimenevän
pinnan sulkemiseen (modaali, popover, valikko). Kohdistuksen on oltava näkyvä
— ei koskaan outline: none; ilman korvaajaa. Kohdistuksen on
liikuttava järkevästi — kun modaali avautuu, kohdistus siirtyy siihen; kun
modaali suljetaan, kohdistus palaa sen avanneeseen elementtiin.
Testaa näppäimistöllä ennen kuin testaat hiirellä;
hiiri piilottaa virheet, jotka näppäimistö paljastaa välittömästi.
Saavutettavat nimet ja kuvaukset
Ei aria-label-ripottelua. Saavutettava nimi tulee oletuksena
elementin tekstisisällöstä; aria-labelledby
viittaa toisen solmun tekstiin; aria-label korvaa
kaiken kovakoodatulla merkkijonolla (ja sen pitäisi olla viimeinen
keinosi, koska se ohittaa käännökset ja taipuu irtautumaan näkyvästä
etiketistä). Saavutettava kuvaus on erillinen —
aria-describedby viittaa ohjeteksti- tai
virheilmoitussolmuun. Tarkista DevToolsin saavutettavuuspuusta,
mitä ruudunlukuohjelma todella vastaanottaa — oletukset ja
todellisuus ovat usein eri mieltä.
Testaa oikeassa CI-ympäristössäsi, ei vain paikallisesti
Paikallinen axe-tarkistus on järkevyystesti. Vihreä CI on regressioportti.
Kytke eslint-plugin-jsx-a11y jokaiseen PR:ään;
lisää axe-core-väittämät yksikkö- ja e2e-testeihin; aja
AT-driver-virtauksia edustavilla sivuilla, jotta oikea ruudunlukuohjelma
on mukana. Ruudunlukijatestaustyökalujen
katsaus kattaa, mitä kannattaa automatisoida ja mikä vaatii edelleen manuaalisen läpikäynnin.
Työkaluketju — 13 valikoitua työkalua ja kirjastoa
Kukin merkintä kuvaa elinkaarivaihetta — lint, yksikkötesti, e2e, ajonaikainen, seuranta tai manuaalinen katselmointi — jotta oikea työkalu voidaan kytkeä oikeaan porttiin.
-
Ajonaikainen
axe-core
Saavutettavuustestausmoottori, joka toimii useimpien alla lueteltujen työkalujen perustana. Lisää se yksikkötesteihin, e2e-paketteihin tai kytke kehitysaikaiseen DOM-ympäristöön ajonaikaisia tarkistuksia varten.
-
E2E
axe DevTools
Selainlaajennus, jossa on integraatiot Playwrightille, Cypressille, Jestille ja Seleniumille. Oletusarvoinen kehittäjäkäyttöliittymä axe-coren päälle.
-
Staattisen analyysin lint-säännöt React JSX:lle. Tarttuu helppoihin puutteisiin (puuttuva alt, virheelliset roolit, onClick div-elementillä) ennen koodikatselmointia.
-
Ajonaikainen
vue-axe
Vuen ajonaikainen saavutettavuustarkistin — tuo axe-coren löydökset selaimen konsoliin kehityksen aikana.
-
Yksikkötesti
@testing-library/jest-dom
Saavutettavuuslähtöiset kysely-matcherit yksikkötesteille. Kannustaa etsimään solmuja ruudunlukuohjelman tapaan (roolin ja saavutettavan nimen mukaan) eikä luokan mukaan.
-
Päästä päähän -selainautomaatio ensiluokkaisella axe-core-integraatiolla. Suorita saavutettavuustarkistuksia oikeissa selaimissa CI:ssä.
github.com/dequelabs/axe-core-npm/tree/develop/packages/playwright ↗
-
Yksikkötesti
Storybook a11y addon
Komponenttikohtainen axe-core-skannaus suunnittelujärjestelmässä. Tarttuu rikkomuksiin ennen kuin ne päätyvät tuotantokoodiin.
-
Seuranta
Pa11y
CLI-skanneri, joka kietoo axe-coren ja HTML CodeSnifferin ympärilleen. Sopiva primitiivi CI-portille, joka kaataa buildin regressioiden sattuessa.
-
Seuranta
Lighthouse CI
Googlen kehittämä, sisältää saavutettavuusauditoinnin (axe-core konepellin alla) sekä suorituskyky- ja hyvien käytäntöjen pisteet. Hyödyllinen trendin seuraamiseen.
-
Manuaalinen
WebAIM WAVE
Visuaalinen skanneri, joka merkitsee ongelmat suoraan sivulle. Sopii suunnittelijoille ja sisällöntuottajille, jotka eivät halua kahlata JSON-raportteja.
-
Yksikkötesti
Wallaby + axe-core integration
IDE-palautesilmukka — ajaa axe-core-väittämät testikohdistimen vieressä. Tiivistää kehittäjän iterointinopeutta uuden komponentin kytkentävaiheessa.
-
W3C:n inkuboima standardi oikeiden ruudunlukuohjelmien ohjaamiseen automatisoiduista testeistä. Automatisoidun saavutettavuustestauksen eturintama — vihdoin axe-tyylisten staattisten tarkistusten tuolla puolen.
-
Manuaalinen
NVDA + JAWS + VoiceOver
Ruudunlukuohjelmat, joita käyttäjät oikeasti käyttävät. Mikään automaatio ei korvaa manuaalista ruudunlukijatestausta niiden 30–40 prosentin WCAG-ongelmien osalta, joita automaatio ei tavoita.
Kehyskohtaiset oppaat
Saavutettavuuden sudenkuopat, jotka muuttavat muotoaan ekosysteemien välillä — ja syvempi käsittely kustakin.
React
Avaimet listoissa (väärin avaimet saavat ruudunlukuohjelmat hämmentymään
kohteiden järjestyessä uudelleen). Kohdistuksenhallinta reitin vaihtuessa
(ilman sitä kohdistus jää navigoinnin käynnistäneeseen linkkiin ja uusi sivu
on näkymätön AT-käyttäjille). Portalit ja kohdistusloukut — modaali, joka
renderöidään document.body:hen, täytyy silti pitää
kohdistus sisällään. Hydraatioristiriidat, jotka muuttavat DOM-rakennetta
SSR:n ja asiakkaan välillä, voivat hiljaisesti rikkoa ARIA-suhteet. Syvällinen
katsauksemme
aria-live-alueista moderneissa kehyksissä
kattaa live-alueiden ilmoitusmallin, jonka Reactin täsmäytys taipuu rikkomaan.
Vue / Svelte / Solid
Samanlaiset mallit; reaktiiviset tilamuutokset, jotka eivät oletuksena käynnistä
live-aluepäivityksiä. Kunkin kehyksen reaktiivisuusmalli määrittelee "DOM on
muuttunut" eri tavoin, ja ruudunlukuohjelmat näkevät — tai eivät näe —
tuloksena syntyvän solmupäivityksen hienovaraisesti eri tavoilla. Vuen
v-if versus v-show, Svelten reaktiiviset
määrittelyt ja Solidin hienojakoinen reaktiivisuus tuottavat erilaisia
saavutettavuuspuupäivityksiä näennäisesti samalle koodille.
Natiivimobiili (iOS + Android)
Täysin erilainen API-pinta. iOS altistaa UIAccessibilityn
(ja SwiftUI:n .accessibilityLabel() /
.accessibilityHint()) VoiceOverille; Android altistaa
AccessibilityNodeInfon TalkBackille. Web-tyylinen ARIA ei käänny.
Natiivimobiilisaavutettavuuden API-artikkeli
yhdistää web-konseptit niiden natiiveihin vastineisiin, jotta
web-koulutuksen saaneet insinöörit voivat lopettaa arvaamisen.
Komponenttikirjastot
Headless-kirjastot (Radix UI, Headless UI, React Aria) hoitavat vaikeat osat — kohdistuksenhallinta, näppäimistökäsittely, ARIA-kytkentä — ja jättävät visuaalisen suunnittelun täysin sinulle. Täysimittaiset kirjastot (Material UI, Chakra, Ant) toimitetaan mielipiteillä varustettuna visuaalisesta puolesta, mutta vaihtelevat laajasti saavutettavuuslaadussa, ja "oletuksena saavutettava" tarkoittaa harvoin "auditoitu oikeilla ruudunlukuohjelmilla". Saavutettavien komponenttikirjastojen katsauksemme arvioi tärkeimmät vaihtoehdot todellista AT-testausta vasten.
PR-katselmoinnin tarkistuslista saavutettavuudelle
Tulosta, liitä PR-mallipohjaan tai automatisoi bottiin. Minimi, jonka jokaisen katselmoijan tulisi vilkaista.
- Interaktiiviset elementit toimivat pelkällä näppäimistöllä (Tab + Enter + Space + Esc).
- Kohdistusindikaattori on näkyvissä jokaisessa interaktiivisessa elementissä.
- Lomakekentillä on niihin liitetty
<label>. - Virheilmoitukset on liitetty kenttiin (
aria-describedbytai viereinen teksti). - Dynaamisen sisällön muutokset ilmoitetaan
aria-live-attribuutilla tarpeen mukaan. - Modaaliset valintaikkunat pitävät kohdistuksen ja palauttavat sen avaajalle suljettaessa.
- Kuvissa on merkityksellinen vaihtoehtoinen teksti; koristeelliset kuvat kantavat
alt="". - Listat käyttävät
<ul>/<ol>/<dl>— ei<div>-salaattia. - Otsikkohierarkia on järkevä (ei ohitettuja tasoja).
- Lint + axe-testit läpäisevät CI:ssä ennen yhdistämistä.
Yleisiä insinöörityön antimalleja
Mallit, jotka läpäisevät koodikatselminnin ja hajoavat tuotannossa. Tavoita ne aiemmin.
- "Overlay-widget" — kolmannen osapuolen JavaScript, joka väittää lisäävänsä saavutettavuutta olemassa olevalle sivustolle. Se ei lisää, se rikkoo usein avustavan teknologian kerroksen, ja se on synnyttänyt oman aaltomaisensa oikeudenkäyntejä. Tausta: overlay-toimittajat.
-
role="button"<div>-elementillä — lisää roolin ilmoittamisen ilman näppäimistökäyttäytymistä (Enter, Space) tai tabin osallistumista. Käytä<button>-elementtiä. -
aria-hidden="true"fokusoitavilla elementeillä — luo kohdistusloukun, jossa näppäimistökäyttäjät voivat tabuloida elementtiin, jolle ruudunlukuohjelma on käsketty olemaan huomioimatta. Joko poista elementti tab-järjestyksestätabindex="-1"-attribuutilla tai poistaaria-hidden. - Mukautettu pudotusvalikko ilman näppäimistökäsittelyä —
<div>-pohjainen yhdistelmäruutu, joka avautuu klikattaessa mutta ohittaa nuolinäppäimet, Homen/Endin, ennakkohakutyypin ja Escin. Saavutettavien komponenttikirjastojen katsaus kattaa kirjastot, jotka hoitavat tämän oikein heti paketista. - Toast-ilmoitukset, jotka eivät ilmoita —
ohimenevä pinta renderöity ilman
role="status"(polite) tairole="alert"(assertive). Näkevät käyttäjät näkevät sen; ruudunlukuohjelmien käyttäjät eivät. - Generoitu DOM, joka rikkoo saavutettavuuspuun
— raskaat kääreelementit input-elementin ympärillä (mukautettu select
rakennettu kahdestatoista sisäkkäisestä
<div>-elementistä) piilottavat usein varsinaisen ohjauselementin AT:ltä. Testaa, mitä AT näkee, ei vain sitä, mitä käyttäjä näkee.
Toolkit + seurantaputkilinja
Useimmat tiimit haluavat kolme asiaa järjestyksessä: kertaluonteisen triaagisskannauksen silloin, kun jokin näyttää rikkinäiseltä; insinööriteoksen, kun he haluavat ymmärtää taustalla olevat mallit; ja jatkuvan seurantakerroksen, kun saavutettavuus siirtyy tuotannon tiekarttaan. Ilmainen WCAG 2.2 -skanneri kattaa ensimmäisen — liitä julkinen URL, saat axe-pohjaisen raportin uuteen välilehteen. Artikkelipöydän insinöörisisältö kattaa toisen — mukaan lukien saavutettavuusvelka teknisenä velkana ja saavutettavuushäiriöt SRE-jälkianalyyseina tiimeille, jotka hallitsevat saavutettavuutta laajassa mittakaavassa.
Jatkuvaa kerrosta varten seurannan ostajan opas on sivuston kantaaottavin teos. Se arvioi axe Monitorin, Siteimproven, Level Accessin ja Qualiboothin — viimeinen integroi seurannan manuaalisen auditoinnin luovuttamiseen, puuttuvan palan useimmissa pelkkään automaatioon perustuvissa pinoissa — kattavuuden laajuuden, väärien positiivisten asteen ja sen mukaan, kuinka siististi data kytkeytyy insinöörityövirtoihin. Seurannan koko tarkoitus on varmistaa, että tänään toimitetut korjaukset eivät regressoidu ensi sprintissä.
Usein kysytyt insinöörityökysymykset
Kysymykset, jotka nousevat esiin jokaisessa saavutettavuuden aloituspalaverissa. Peilattu FAQPage-rakenteisiin tietoihin.
- Onko
aria-labelparempi kuin näkyvät tekstietikettit? -
Ei. Näkyvä teksti on lähes aina parempi — se hyödyttää näkeviä
käyttäjiä, näkeviä käyttäjiä, joilla on kognitiivisia vammoja, ääniohjauksen
käyttäjiä (jotka sanovat sen, mitä näkevät) ja käännöstyökaluja.
Turvaudu
aria-labeliin vain silloin, kun näkyvää tekstiä ei ole yhdistettävissä (pelkkä ikoni -painikkeet) tai kun näkyvä teksti ei todella ole haluamasi saavutettava nimi. - Pitäisikö ARIA-rooleja käyttää kaikkialle?
-
Ei. ARIA:n ensimmäinen sääntö on "do not use ARIA". Natiivin HTML-elementeissä on
oikea rooli, oikea näppäimistökäyttäytyminen
ja oikea saavutettavuuspuun semantiikka sisäänrakennettuna. Käytä ARIA:a
silloin (ja vain silloin), kun sopivaa natiivielementtiä ei ole —
esimerkiksi välilehtilista, puu tai mukautettu valintaikkuna, jossa et voi
käyttää
<dialog>-elementtiä. - Miten testaan saavutettavuutta CI:ssä?
-
Kolme kerrosta kustannusjärjestyksessä. (1) Lint:
eslint-plugin-jsx-a11yjokaisessa PR:ssä. (2) Yksikkötestit:@testing-library/jest-domsekäjest-axe(tai@axe-core/react) jokaiselle komponentille. (3) Päästä päähän:@axe-core/playwrightedustavilla käyttäjäpoluilla. Lisää Pa11y- tai Lighthouse CI -portti stagingiin, jotta alempien kerrosten ohittama ajautuminen jää kiinni. - Ovatko axe-core ja Lighthouse sama asia?
- Lighthouse käyttää axe-corea konepellin alla saavutettavuusauditointiaan varten, mutta ajaa valikoitua osajoukkoa säännöistä ja esittää ne laajemman suorituskyky- / SEO / hyvät käytännöt -raportin sisällä. axe-core itse on moottori — kun haluat koko sääntöjoukon tai haluat laajentaa sitä, käytät axe-corea suoraan. Useimmille tiimeille: käytä Lighthousea trendin seuraamiseen, axe-corea varsinaiseen porttiin.
- Mikä on minimaalinen saavutettavuustestauksen konfiguraatio React-projektille?
-
Lisää
eslint-plugin-jsx-a11yolemassa olevaan ESLint- konfiguraatioon (se toimitetaan oletuksena create-react-appin ja Next.js:n kanssa). Lisää@testing-library/jest-domjajest-axeyksikkötestikonfiguraatioon ja kutsuexpect(await axe(container)).toHaveNoViolations()vähintään yhdessä testissä per komponentti. Se on lattia — tarttuu noin 40 prosenttiin todellisista WCAG-ongelmista muutaman tunnin konfiguraatiolla. - Tarvitseeko testata oikeilla ruudunlukuohjelmilla?
- Kyllä, kaikkien tuoteominaisuuksien osalta, joita avustavan teknologian käyttäjä todella käyttää. Automaattiset työkalut tavoittavat rakenteelliset virheet (puuttuvat etikettit, kontrasti, rooliristiriidat) mutta eivät kokemukselliset (kohdistus, joka hyppää alatunnisteeseen, live-alueet, jotka eivät ilmoita, "saavutettava" modaali, joka loukkaa kohdistuksen väärään alipuuhun). Suunnittele vähintään yksi manuaalinen läpikäynti jokaista merkittävää julkaisua varten NVDA:lla Windowsilla ja VoiceOverilla macOS:llä / iOS:llä.
Seuraavat askeleet
Aja nopea tarkistus ilmaisella WCAG 2.2 -skannerilla, jos teet triaagia tietyllä sivulla. Lue ruudunlukijatestaustyökalujen katsaus ennen kuin kytket AT-driverin CI:hin. Ja jos saavutettavuus on siirtymässä "kertaluonteisesta auditoinnista" "jatkuvaksi tuotannon huoleksi", seurannan ostajan opas on sivuston konkreettisin teos toimittajan valitsemiseksi.