Tilgængelige formularer uden hovedpine
Det meste a11y sidder i de små ting
De fleste tilgængelighedsproblemer i små webprojekter handler ikke om vilde ARIA-tricks, men om helt basale ting som labels, knapper og fokus-styles. Fixer du dem, er du allerede foran en stor del af internettet.
Jeg opdagede det første gang, da jeg prøvede at tabbe mig igennem min egen side og forsvandt ind i et sort hul mellem to formularfelter. Siden så fin ud med mus, men den var ærligt talt ubrugelig uden.
80/20 tilgængelighed i små projekter
Hvis du bygger personlige projekter, behøver du ikke kunne hele WCAG udenad. Du har brug for en lille kerne af vaner, der gør dine ting brugbare for langt de fleste.
For typiske portfolio-sider, små værktøjer og skolesites giver det her mest effekt:
- Formularer med rigtige
<label>,nameog meningsfulde fejlbeskeder - Korrekt brug af
<button>vs.<a> - God tastaturnavigation og tydelige fokus-states
- Kun lidt, men velplaceret ARIA, når HTML ikke rækker
Resten kan du bygge på senere. Lidt som at lære akkorder før jazz-improvisation.
Formularer der giver mening for flere end dig
En formular er ikke bare inputfelter og en send-knap. Den er en lille dialog mellem brugeren og siden. Hvis den dialog kun fungerer visuelt, falder mange fra.
Så vi starter med tre ting, der næsten altid er galt i begyndersider: labels, name-attributter og autocomplete.
Label og input der faktisk hænger sammen
Typisk fejl: man skriver placeholder-tekst og glemmer labels. Det ser pænt ud, lige indtil placeholderen forsvinder, og brugeren ikke kan huske, hvad feltet var til.
Det her er den gode, gamle, kedelige, men rigtige måde:
<label for="email">Email</label>
<input
type="email"
id="email"
name="email"
autocomplete="email"
/>
Nøglen er for på label og id på input, der matcher. Screen readers og tastaturbrugere ved nu, hvad feltet betyder, og du kan klikke på label og fokusere feltet.
Hvis du vil style med label inde i feltet, så brug hellere CSS end at droppe label helt. Du kan f.eks. bruge position: absolute; på label og flytte den.
name og autocomplete der faktisk hjælper
name bruges til at sende data til serveren, men det hjælper også browseren med at huske felter. Uden name er feltet nærmest anonymt.
Et fornuftigt login-udsnit kunne se sådan her ud:
<label for="user-email">Email</label>
<input
type="email"
id="user-email"
name="email"
autocomplete="email"
/>
<label for="password">Adgangskode</label>
<input
type="password"
id="password"
name="password"
autocomplete="current-password"
/>
autocomplete gør to ting: hjælper brugeren med autofill og hjælper password managers med at forstå, hvad feltet er. Det gør oplevelsen lettere for alle, ikke kun “tilgængelighedsbrugere”.
Validering: vis fejl på en måde alle kan forstå
Den mest klassiske aften-jeg-troede-jeg-havde-ødelagt-alt-fejl jeg selv har lavet, var en formular, der “ikke gjorde noget”. I virkeligheden fejlede den bare, uden jeg viste det nogen steder.
En god fejlbesked skal:
- Være tæt på feltet, den handler om
- Være tekst, ikke kun farve
- Kunne findes af screen readers
Her er et lille mønster, du kan genbruge:
<label for="age">Alder</label>
<input
type="number"
id="age"
name="age"
aria-describedby="age-error"
aria-invalid="true"
/>
<p id="age-error" class="error">
Skriv din alder som et tal mellem 1 og 120.
</p>
aria-invalid="true" fortæller hjælpemidler, at feltet er i fejltilstand. aria-describedby binder fejlteksten til feltet. Brugeren får både visuel tekst og teknisk sammenhæng.
Hvis du vil se mere om, hvorfor semantik og tilgængelighed hænger sammen, så giver denne artikel på Coding Class om semantiske tags et godt udgangspunkt.
Knapper og links uden forvirring
Mange UI-fejl starter med én ting: alt er blevet lavet som et link. Eller alt er en <div> med en click-handler.
Det gør siden svær at bruge uden mus og forvirrer screen readers.
Hvornår er det en knap, og hvornår er det et link?
Tom regel:
- Noget, der ændrer siden (åbner modal, sender formular, toggler menu) er typisk en
<button> - Noget, der går til en anden side eller URL, er et
<a>
Sådan her:
<!-- Korrekt: knap der åbner en menu -->
<button type="button">Åbn menu</button>
<!-- Korrekt: link til en anden side -->
<a href="/profil">Gå til din profil</a>
Hvis du styler dine knapper som links eller omvendt, er det helt fint. Bare brug de rigtige HTML-tags under overfladen.
Klikbare divs og spans, der ikke opfører sig som klik
Hvis du laver noget som det her, får tastaturbrugere det svært:
<div class="btn" onclick="openModal()">
Åbn modal
</div>
Divs kan ikke fokuseres med tastatur som standard, og de annonceres ikke som klikbare. Så man ved ikke, at der “sker noget”.
Løsningen er egentlig kedelig:
<button type="button" onclick="openModal()">
Åbn modal
</button>
Hvis du tabindex og keydown-handlers, og så er det hurtigere at bruge en rigtig knap.
Tastatur: tab-rækkefølge og fokus-styles
En hurtig test jeg altid laver på nye sider: jeg lægger musen væk og prøver at bruge siden med kun tab, enter og space. Hvis jeg farer vild eller mister fokus, er der noget galt.
Den naturlige tab-rækkefølge
Browsere følger DOM-rækkefølgen, når du tabber. Du behøver sjældent sætte tabindex, hvis din HTML er skrevet i en fornuftig rækkefølge.
Undgå især tabindex="-1" på ting, der burde være fokuserbare, og tabindex="0" på alt muligt pynt.
Hvis du bruger mange CSS-tricks til layout, så hold HTML-strukturen nogenlunde i den rækkefølge, du forventer, at brugeren læser siden. Flex og grid kan flytte ting visuelt, men tab følger stadig HTML.
Focus states i CSS: gør dem tydelige, ikke usynlige
En af de største “UX-kriminelle handlinger” er at fjerne fokus-outline uden at erstatte den:
button, a {
outline: none;
}
Hvis du gør det, har tastaturbrugeren ingen idé om, hvor hun er. Du må gerne style fokus selv, men giv den noget synligt.
F.eks. sådan her:
button:focus-visible,
a:focus-visible,
input:focus-visible,
textarea:focus-visible {
outline: 2px solid #2563eb; /* blå */
outline-offset: 2px;
}
:focus-visible viser typisk kun fokus, når brugeren faktisk bruger tastatur, ikke ved mus-klik. Det føles mindre “støjende”, men hjælper der, hvor det skal.
Et lille “skip to content”-mønster
En nem ting, der scorer mange point hos screen reader- og tastaturbrugere, er et “spring til indhold”-link øverst.
Mønstret ser sådan her ud:
<a href="#main" class="skip-link">
Spring til hovedindhold
</a>
<header>...</header>
<main id="main">
... dit indhold ...
</main>
Og CSS:
.skip-link {
position: absolute;
left: -9999px;
top: 0;
background: #111;
color: #fff;
padding: 0.5rem 1rem;
z-index: 1000;
}
.skip-link:focus-visible {
left: 0.5rem;
top: 0.5rem;
}
Så kan man tabbe én gang, trykke enter og hoppe forbi navigation til det vigtige indhold. En lille ting, men det føles markant bedre i brug.
ARIA uden panik: fem små regler
ARIA er det sted, hvor mange begynder at stå af. Jeg gjorde det samme og tænkte “det her lærer jeg senere”. Tricket er at starte lavt: du behøver ikke kunne alt.
Hvis du følger de her fem regler, er du allerede godt kørende:
- 1. Brug semantisk HTML før ARIA. En rigtig
<button>er bedre endrole="button"på en div. - 2. Brug ARIA til at forbinde ting. F.eks.
aria-describedbymellem input og fejltekst. - 3. Markér tilstande. F.eks.
aria-expanded="true"på en menu-knap, når menuen er åben. - 4. Undgå at overskrive native roller, hvis du ikke skal. Du behøver sjældent sætte
role="button"på en<button>. - 5. Hvis du ikke ved, hvad et ARIA-attribut gør, så google det, før du bruger det. Gættet ARIA er værre end ingen ARIA.
Et simpelt eksempel med en fold-ud-sektion:
<button
type="button"
aria-expanded="false"
aria-controls="faq-1"
id="faq-toggle-1"
>
Vis svar
</button>
<div id="faq-1" hidden>
<p>Her er svaret på spørgsmålet.</p>
</div>
Din JavaScript kan så skifte aria-expanded mellem true og false og toggler hidden på div’en. Ingen kæmpe ARIA-orkester, bare lidt tydeligere state.
Mini-øvelse: fix 10 a11y-fejl
Nu til den del, hvor du rent faktisk lærer noget: ret fejl. Det er seriøst den hurtigste måde at få tilgængelighed ind under huden.
Lav en lille HTML-side med f.eks.:
- En navigation med tre links
- En kontaktformular med navn, email, besked og en send-knap
- En “åbn modal”-knap, der bare viser en boks med lidt tekst
Smid så med vilje følgende fejl ind:
- Brug kun placeholders, ingen
<label> - Drop
namepå alle inputs - Gør send-knappen til en
<div>med click-handler - Fjern alle fokus-styles i CSS
- Lav “åbn modal” som et
<a>udenhref - Vis fejlmeddelelser kun med farve (f.eks. rød kant)
- Lav ingen sammenhæng mellem input og fejltekst
- Glem
autocomplete - Ingen “skip to content”-link
- Lad modalens lukkeknap være et lille kryds i et
<span>
Og så: gå dem igennem én for én og fix dem med de mønstre, vi har talt om. Test bagefter med tastatur og, hvis du kan, en screen reader eller f.eks. Chrome’s “Screen Reader” extension.
Hvis du vil kombinere det med semantik, kan du snuppe noget af strukturen fra artiklen om section vs article vs div og bygge oven på den.
Tilgængelighed tjekliste til dit næste portfolio-projekt
Jeg har efterhånden en lille mental tjekliste, jeg kører igennem, hver gang jeg laver en ny side med formularer eller knapper. Du kan stjæle den direkte.
Formularer
- Har alle felter en synlig label, der hænger sammen via
for/id? - Har alle felter et meningsfuldt
name? - Bruger jeg passende
type(email, number, password osv.)? - Er relevante felter forsynet med
autocomplete? - Har jeg tekst-fejlbeskeder, der er forbundet via
aria-describedby, når der er fejl?
Knapper og links
- Bruger jeg
<button>til handlinger og<a>til navigation? - Findes der nogen klikbare divs/spans, der burde være knapper eller links?
- Har alle links et
href, der giver mening?
Tastatur og fokus
- Kan jeg nå alle interaktive elementer med Tab?
- Har jeg tydelige fokus-styles (gerne med
:focus-visible)? - Har jeg et “spring til indhold”-link øverst, der virker?
ARIA
- Bruger jeg primært semantisk HTML i stedet for at lappe med ARIA?
- Hvis jeg bruger ARIA, ved jeg så hvad det konkrete attribut gør?
- Har dynamiske elementer (som fold-ud, modal, dropdown) en klar state, f.eks. med
aria-expanded?
Hvis du har svært ved at huske det hele, så skriv den her liste i din projekt-README eller lav et lille internt “a11y.md” i repoet. Det føles lidt nørdet, men på den gode måde.
Til sidst: det her er en vane, ikke en feature
Jeg ser tilgængelighed som noget, der skal med fra første prototype, ikke som en bonusrunde. Lidt ligesom at gemme ofte, så du ikke mister din tegning, når katten går hen over tastaturet.
Og ja, du kommer til at glemme noget ind imellem, men hver gang du opdager en ny lille a11y-ting og får den rettet, bliver alle dine fremtidige projekter en tand bedre. Det synes jeg faktisk er ret tilfredsstillende.








Send kommentar
Du skal være logget ind for at skrive en kommentar.