Dev Tools & Workflow

En udviklerguide til ARIA-labels, der faktisk hjælper

ARIA-labels er ikke et magisk tilgængelighedslag. Brugt godt gør de kontroller forståelige. Brugt skødesløst skjuler de nyttig tekst og skaber forvirrende grænseflader.

The Wux Webtools Team The Wux Webtools Team 8 min læsning AI-assisteret, menneskelig gennemgået
Illustration of a developer reviewing accessible labels and UI components on a screen.
Indholdsfortegnelse
  1. ARIA-labels er til navne, ikke undskyldninger
  2. Det tilgængelige navn, forklaret enkelt
  3. Første regel: foretræk native HTML og synlige labels
  4. Hvornår `aria-label` er det rigtige værktøj
  5. Hvornår `aria-label` er det forkerte værktøj
  6. Ræk ud efter `aria-labelledby`, når synlig tekst allerede findes
  7. Brug `aria-describedby` til hjælpetekst, ikke navnet
  8. Gentagne kontroller har brug for unikke navne
  9. Label ikke alt
  10. Tjek det beregnede navn, ikke kun koden
  11. En praktisk tjekliste til gennemgang
  12. Den stille disciplin i god ARIA

ARIA-labels er til navne, ikke undskyldninger

ARIA er nyttigt, men det bruges ofte som en lappeløsning for uklar HTML. Det er her, teams kommer i problemer.

Det mest almindelige eksempel er aria-label. Det ser harmløst ud: tilføj en streng, tilfredsstil en linter, gå videre. Men et tilgængeligt navn er ikke pynt. Det er det navn, mange hjælpeteknologier viser eller oplæser for brugere, når de navigerer efter knapper, links, formularfelter, overskrifter, landmarks og kontroller.

Hvis det navn er vagt, duplikeret, forældet eller forskelligt fra den synlige label, bliver grænsefladen sværere at bruge. Nogle gange værre: aria-label kan overskrive bedre tekst, der allerede fandtes i DOM’en.

Målet er ikke at tilføje mere ARIA. Målet er at gøre navn, rolle, tilstand og formål for hvert grænsefladeelement tydeligt.

Det tilgængelige navn, forklaret enkelt

De fleste interaktive elementer har et tilgængeligt navn. Skærmlæsere bruger det navn til at annoncere, hvad elementet er.

For eksempel:

<button>Save changes</button>

En skærmlæser kan annoncere noget i retning af: “Save changes, knap.” Rollen kommer fra det native button-element. Navnet kommer fra teksten inde i det.

Det er idealsituationen: synlig tekst og tilgængeligt navn matcher.

ARIA-label-attributter bliver nyttige, når den synlige grænseflade ikke giver et fuldstændigt navn, eller når navnet skal komme fra et andet element. De vigtigste attributter er:

  • aria-label: angiver en streng direkte på elementet.
  • aria-labelledby: peger på et eller flere elementer, hvis tekst bliver navnet.
  • aria-describedby: peger på understøttende beskrivelsestekst, ikke hovednavnet.

De tre hænger sammen, men de kan ikke bruges i flæng.

Første regel: foretræk native HTML og synlige labels

Hvis du kan placere synlig tekst på kontrollen, så gør det først.

Dette er bedre:

<button>Delete invoice</button>

End dette:

<button aria-label="Delete invoice">
  <svg aria-hidden="true" focusable="false">...</svg>
</button>

Det andet mønster er gyldigt for en knap, der kun består af et ikon. Men hvis designet kan tolerere synlig tekst, hjælper synlig tekst alle: skærmlæserbrugere, brugere af talegenkendelse, personer med kognitiv belastning, personer der scanner hurtigt, og personer der bruger oversættelsesværktøjer.

Dette er et tilbagevendende tema i tilgængelighedsarbejde. Native HTML og synlige affordances løser flere problemer end skjulte metadata. Det samme princip gælder knapsemantik mere bredt; hvis dit team gennemgår UI-kontroller, er vores tjekliste for tilgængelige webknapper et godt supplement til denne guide.

Hvornår aria-label er det rigtige værktøj

Brug aria-label, når et element har brug for et tilgængeligt navn, og der ikke findes passende synlig tekst at referere til.

Det klassiske tilfælde er en knap, der kun består af et ikon:

<button aria-label="Search">
  <svg aria-hidden="true" focusable="false" viewBox="0 0 24 24">
    <!-- icon -->
  </svg>
</button>

Det er rimeligt. Det synlige ikon antyder søgning, men SVG-stien i sig selv giver ikke et pålideligt navn. aria-label leverer et.

Andre gode tilfælde omfatter:

  • En luk-knap, der kun er repræsenteret af et “X”.
  • Et navigation-landmark, der har brug for et mere specifikt navn, såsom aria-label="Product".
  • En gentaget kontrol, hvor synlig kontekst ikke er en del af knappens tekst.

For eksempel:

<nav aria-label="Primary">
  ...
</nav>

<nav aria-label="Footer">
  ...
</nav>

Begge er navigation-landmarks, men deres labels hjælper brugere med at skelne mellem dem, når de bevæger sig efter landmarks.

Hvornår aria-label er det forkerte værktøj

Tilføj ikke aria-label, bare fordi en test siger, at et element har brug for en label. Ret markuppen først.

Dårligt:

<div role="button" tabindex="0" aria-label="Submit">Submit</div>

Bedre:

<button>Submit</button>

Det første eksempel skaber unødigt arbejde. Du skal nu genskabe tastaturadfærd, deaktiverede tilstande, formularadfærd og forventninger, som native knapper allerede leverer.

Undgå også at bruge aria-label til at omdøbe synlig tekst på en måde, der ændrer betydningen.

<button aria-label="Delete invoice">Remove</button>

Det ser måske ubetydeligt ud, men det kan forvirre brugere, der er afhængige af taleinput. Hvis en synlig knap siger “Remove”, men dens tilgængelige navn er “Delete invoice”, får en bruger, der prøver at sige “klik Remove”, måske ikke det forventede resultat. WCAG’s krav om “label in name” findes netop af den grund: synlig tekst bør som regel være indeholdt i det tilgængelige navn.

En bedre version:

<button aria-label="Remove invoice">Remove</button>

Ofte endnu bedre:

<button>Remove invoice</button>

Ræk ud efter aria-labelledby, når synlig tekst allerede findes

Hvis label-teksten allerede er på siden, er aria-labelledby som regel bedre end aria-label.

Eksempel:

<h2 id="billing-title">Billing address</h2>
<section aria-labelledby="billing-title">
  ...
</section>

Sektionens tilgængelige navn kommer nu fra den synlige overskrift. Du undgår at duplikere strenge, hvilket reducerer oversættelsesfejl og forældede labels.

Dette er især nyttigt for formulargrupper:

<fieldset aria-labelledby="shipping-speed-title">
  <legend id="shipping-speed-title">Shipping speed</legend>

  <label>
    <input type="radio" name="shipping" value="standard">
    Standard
  </label>

  <label>
    <input type="radio" name="shipping" value="express">
    Express
  </label>
</fieldset>

I mange tilfælde er den native legend nok uden ARIA. Pointen er, at synlige labels bør føre an. ARIA bør forbinde eksisterende betydning, ikke skabe en anden privat version af den.

Brug aria-describedby til hjælpetekst, ikke navnet

En beskrivelse er ikke en label.

Overvej dette felt:

<label for="password">Password</label>
<input id="password" type="password" aria-describedby="password-help">
<p id="password-help">Use at least 12 characters.</p>

Det tilgængelige navn er “Password.” Beskrivelsen er “Use at least 12 characters.” En skærmlæser kan annoncere begge, men de har forskellige formål.

Gør ikke dette:

<input type="password" aria-label="Use at least 12 characters">

Det navngiver feltet efter instruktionen, ikke efter begrebet. En bruger, der navigerer i en formular, vil først vide, hvad feltet er, og derefter hvilke begrænsninger der gælder.

Denne skelnen er også vigtig i fejltilstande:

<label for="email">Email</label>
<input
  id="email"
  type="email"
  aria-invalid="true"
  aria-describedby="email-error"
>
<p id="email-error">Enter an email address in the format [email protected].</p>

Labelen forbliver stabil. Fejlmeddelelsen bliver understøttende kontekst.

Gentagne kontroller har brug for unikke navne

Lister og kort er steder, hvor ARIA-labels ofte bliver nødvendige.

Dårligt:

<button>Delete</button>
<button>Delete</button>
<button>Delete</button>

En skærmlæserbruger, der navigerer efter knapper, kan høre “Delete, knap” tre gange uden kontekst.

Godt:

<button aria-label="Delete report: Q4 revenue">Delete</button>
<button aria-label="Delete report: Hiring plan">Delete</button>
<button aria-label="Delete report: Vendor list">Delete</button>

Dette er en legitim brug af aria-label: Den synlige tekst forbliver kort, mens det tilgængelige navn inkluderer objektet.

Men brug dette mønster med omtanke. Hvis objektets navn er synligt i nærheden, kan aria-labelledby være lettere at vedligeholde:

<article>
  <h3 id="report-q4">Q4 revenue</h3>
  <button aria-labelledby="delete-q4 report-q4" id="delete-q4">Delete</button>
</article>

Det tilgængelige navn bliver “Delete Q4 revenue.” Det undgår at duplikere rapporttitlen i en attribut.

Label ikke alt

Ikke alle elementer har brug for en ARIA-label.

Statisk tekst har som regel ikke. Dekorative ikoner har ikke. Containere har ikke, medmindre de har et meningsfuldt landmark eller en widget-rolle. Over-labeling kan gøre en side støjende og sværere at navigere.

For billeder skal du bruge den billedspecifikke model: meningsfulde billeder har brug for nyttig alt; dekorative billeder har brug for tom alt="". Brug ikke ARIA-labels som erstatning for god billedtekst. Hvis dit team blander disse begreber sammen, så genbesøg pragmatisk alt-tekst til billeder og adskil billedalternativer fra kontrolnavne.

En almindelig fejl er at give hver SVG en aria-label. Hvis SVG’en er inde i en knap, og knappen allerede har et navn, bør ikonet som regel skjules for hjælpeteknologi:

<button aria-label="Open menu">
  <svg aria-hidden="true" focusable="false">...</svg>
</button>

Ellers kan brugeren høre overflødige eller mærkelige annonceringer afhængigt af kombinationen af browser og hjælpeteknologi.

Tjek det beregnede navn, ikke kun koden

Tilgængelighedsfejl overlever ofte kodegennemgang, fordi markuppen ser plausibel ud.

Moderne browserudviklerværktøjer kan vise det beregnede accessibility tree. I Chrome, Edge, Firefox og Safari kan du inspicere elementet og lede efter tilgængelighedsoplysninger som rolle, navn og beskrivelse. Du tjekker tre ting:

  1. Er rollen, hvad du forventer?
  2. Er det tilgængelige navn klart og specifikt?
  3. Er beskrivelsen hjælpsom uden at erstatte navnet?

Test derefter nogle få flows med en rigtig skærmlæser. Du behøver ikke blive fuldtids-ekspert i hjælpeteknologi for at fange det grundlæggende. På macOS er VoiceOver indbygget. På Windows er NVDA udbredt og gratis. På mobil skal du teste med VoiceOver på iOS og TalkBack på Android, hvor det er relevant.

Automatiserede værktøjer er nyttige, men de kan ikke pålideligt fortælle, om “Open”, “Read more” eller “Delete” er tilstrækkeligt kontekstuelle. Behandl automatisering som et net, ikke en dommer. Det minder om performance-auditing: En rapport kan pege dig mod mistænkelige områder, men du skal stadig fortolke effekten. Den samme rolige tilgang, vi anbefaler til at læse en Lighthouse-rapport uden panik, gælder her.

En praktisk tjekliste til gennemgang

Før du shipper ARIA-labels, så spørg:

  • Kunne dette være native HTML i stedet?
  • Findes der synlig tekst, der bør bruges som label?
  • Hvis der findes synlig tekst, inkluderer det tilgængelige navn den så?
  • Er gentagne kontroller unikke, når de navigeres uden visuel kontekst?
  • Er hjælpetekst forbundet med aria-describedby og ikke presset ind i labelen?
  • Er dekorative ikoner skjult for hjælpeteknologi?
  • Har nogen tjekket det beregnede tilgængelighedsnavn i browserens dev tools?
  • Er der gennemført mindst én test med en rigtig skærmlæser for det kritiske flow?

Denne tjekliste fanger de fleste label-problemer, før de bliver brugerproblemer.

Den stille disciplin i god ARIA

Godt ARIA-arbejde er sjældent dramatisk. Det handler mest om tilbageholdenhed.

Brug rigtige knapper. Brug rigtige labels. Hold synlige og tilgængelige navne på linje. Tilføj kun aria-label, når der ikke findes en bedre synlig kilde. Brug aria-labelledby, når siden allerede indeholder den rigtige tekst. Brug aria-describedby til understøttende instruktioner og fejl.

Webplatformen giver udviklere meget gratis, når vi bruger den direkte. ARIA er der til hullerne. Færdigheden er at vide, hvornår der faktisk er et hul.

Ofte stillede spørgsmål

Bør alle knapper have en aria-label?
Nej. En knap med tydelig synlig tekst har som regel allerede et godt tilgængeligt navn. Tilføj kun `aria-label`, når den synlige tekst mangler eller er utilstrækkelig, såsom en knap der kun består af et ikon, eller en gentaget “Delete”-knap, der har brug for kontekst.
Hvad er forskellen på aria-label og aria-labelledby?
`aria-label` angiver en tekststreng direkte i attributten. `aria-labelledby` peger på eksisterende tekst et andet sted på siden. Hvis der allerede findes passende synlig tekst, er `aria-labelledby` som regel lettere at vedligeholde.
Kan aria-label rette en div, der bruges som en knap?
Den kan give et navn, men den får ikke elementet til at opføre sig som en rigtig knap. Du skal stadig håndtere tastaturadfærd, fokus, tilstande og forventet semantik. I de fleste tilfælde bør du bruge en native `<button>`.
Bør aria-label matche den synlige tekst præcist?
Den bør som regel inkludere den synlige tekst, især for interaktive kontroller. Det understøtter brugere af talegenkendelse og opfylder intentionen bag WCAG’s label-in-name-vejledning.
Hvordan ved jeg, hvad en skærmlæser vil annoncere?
Start med at tjekke accessibility tree i browserens udviklerværktøjer for rolle, navn og beskrivelse. Test derefter kritiske interaktioner med en rigtig skærmlæser som VoiceOver, NVDA, TalkBack eller JAWS.

Kilder & videre læsning

  1. WAI-ARIA Authoring Practices Guide
  2. MDN: aria-label attribute
  3. Accessible Name and Description Computation 1.2
  4. WCAG 2.2 Success Criterion 2.5.3: Label in Name
Om forfatteren
The Wux Webtools Team

Sidst opdateret:

Fortsæt med at læse