Håndtering af overskudsniveauer i designsystemer

Én ting, der fortsætter med at vende tilbage til mig, inden for forskning, test og daglig samtale med kolleger og venner, er lige så vigtige overskrifter. For brugere af skærmlæser beskriver overskrifter forholdet mellem sektioner og underafsnit og - når de bruges korrekt - giver både et kontur og et navigationsmiddel. Overskrifter er infrastruktur.

Anvendelse af det rigtige overskriftniveau er et spørgsmål om kontekst. For eksempel beskriver to på hinanden følgende overskrifter på samme niveau to søskensektioner i dokumentoversigten. Hvor den anden af ​​de successive overskrifter er et højere niveau, beskriver den en underafsnit, der hører til det første overskuds afsnit.

alt tekst = på billedet er der to bokse efter hinanden, markeret som h2 niveau søskende. Inde i den anden boks er en tredje kasse markeret som et h3-niveau underafsnit.

HTML5 lovede at automatisere disse forhold ved at udskyde hekkealgoritmen til s (eller andre sektionselementer). Ideen var, at bogstaveligt indlejring af overordnede -elementer i DOM, deres overskriftsniveauer ville blive justeret gratis i tilgængelighedstræet. (Tilgængelighedstræet er fortolkningen af ​​den DOM, der er kommunikeret til software, såsom skærmlæsere.)

  

Sektionsoverskrift

  
    ` til skærmlæsere ->     

Underoverskrift

  

Desværre har hidtil ikke nogen større browserudbyder meningsfuldt implementeret denne såkaldte "dokumentkontouralgoritme". Og hvis browseren ikke afslører den, kan skærmlæsere ikke kommunikere den. Det sidste kodeeksempel fungerer bare ikke.

De af os, der er interesseret i at oprette tilgængelige dokumentkonturer, sidder derfor fast ved at vælge overskriftsniveauer (

til

) uanset s, vi muligvis bruger.

  

Sektionsoverskrift

  
    

Underoverskrift

  

Dette udgør et særligt problem, når man udvikler mønsterbiblioteker til designsystemer. Mens individuelle mønstre / komponenter i et designsystem kan - og bør - bruge overskrifter, er det vanskeligt at vide, hvilke overskriftsniveauer de skal tage. Som isolerede moduler i et mønsterbibliotek er konteksten af ​​komponenten på en side ubestemmelig. For genanvendelige komponenter vil konteksten ændres sammen med det krævede niveau.

alt text = På billedet vises en komponent som kan genanvendes i forskellige kontekster på en side. Afhængig af konteksten, skal komponenten have et niveau på h2 eller et h3.

Niveau prop

API'er som React's og Vue lader os manuelt inkludere egenskaber (eller 'rekvisitter') til vores komponenter ved instantiation. Disse giver os mulighed for at anvende visse indstillinger på komponentens instans, der skal bruges internt.

Ved at støtte et niveauoprop kan vi give forfattere mulighed for at justere overskriftsniveauet for komponenten på tidspunktet for instantiering, når de er opmærksomme på dets omgivende kontekst. Sådan anvendes det på den ydre komponent:

 

Internt er vi nødt til at tage det foreskrevne niveau og bruge det til at øge komponentens principoverskrift. Der er et par måder at gøre dette på. Den første måde ville være at anvende en vis logik, der vælger det rigtige overskriftelement (

til

) for os. I React kan vi bruge en komponent som en variabel:

render () {
  const H = 'h' + this.props.level;
  Vend tilbage (
    
       En overskrift på et eller andet niveau       

Lorem ipsum osv.

       ); }

Dette vil hurtigt blive uhåndterligt, når du opretholder en struktur med flere overskrifter i komponenten (se det efterfølgende afsnit). I stedet kan vi ændre overskriftelementets niveau i tilgængelighedstræet direkte via egenskaben på aria-niveau.

To ting at bemærke:

  • Et

    element bruges som en "fornuftig standard". Alle underafsnit i første niveau, der følger sidens princip

    overskrift, vil være af det andet (

    ) niveau. Hvis niveauoprop ikke er angivet, anvendes ikke aria-niveau, og det implicitte andet niveau fungerer som en standard (nulværdien betyder, at attributten ikke gengives).

  • har allerede den implicitte overskriftsrolle, så brugen af ​​role = "overskrift" ville være overflødig. Havde vi brugt en
    til at definere vores overskrift, ville rolle = "overskrift" være nødvendigt sammen med aria-niveau. Dette anbefales ikke, fordi understøttelsen er relativt sparsom. I det mindste hvor aria-niveau ikke understøttes, har vi stadig en

    overskrift - selvom det ikke er det rigtige niveau. Overskrifter, på ethvert niveau, kan navigeres mellem i skærmlæsere som NVDA eller JAWS ved hjælp af h-tasten.

Flere overskrifter

I nogle tilfælde kan undertegnet, der udgør vores komponent, omfatte flere overskrifter, der beskriver en mikrostruktur i dokumentet. Hårdkodning af hvert niveau via sin egen prop ville være ordret og tilbøjelig til fejl fra forfatterens side.


 

I stedet kan vi opretholde den samme struktur ved at anvende nogle enkle aritmetikker.

Overskriftstekst

Lorem ipsum.

Underoverskriftstekst

Lorem ipsum.

Indlejret underoverskriftstekst

Lorem ipsum.

Nu har forfatteren stadig kun brug for at anvende et niveau på øjeblikket (hvis nødvendigt!), Og hele strukturen skifter tilsvarende. Simpelt men effektivt.

Komplet automatisering

Vidste du, at et -element oprindeligt blev opført så tidligt som i 1991 og ville automatisere overskriftsniveauer på den måde, som den sagnomsuste "Document Outline Algorithm" skal? Faktisk diskuteres det stadig.

Som den fremtrædende Sophie Alpert demonstrerede for mig, er det muligt at efterligne denne automatiserede dispositionsadfærd ved hjælp af Reacts relativt nye Context API.

Det smukke ved kontekst er, at du - for at citere dokumenterne - "videregive data gennem komponenttræet uden at skulle give rekvisitter manuelt på alle niveauer". I praksis betyder det, at vi kan justere værdien af ​​niveau blot ved at hekke komponenter.

Først skal vi initialisere konteksten.

const niveau = React.createContext (2);

Bemærk den 2, der indstiller standardniveauet som i tidligere eksempler. Nu skal vi bare konfigurere afsnit og H-komponenter.

funktionsafsnit (rekvisitter) {
  Vend tilbage (
     {niveau =>
      
        {props.children}
      
    } 
  );
}
funktion H (rekvisitter) {
  Vend tilbage (
     {niveau => {
      const Overskrift = 'h' + Math.min (niveau, 6);
      retur ;
    }} 
  );
}

Afsnittet forbruger niveauværdien for det rede niveau (via niveau.forbruger) justerer derefter niveauet for alle børn (niveau + 1).

Hvor ethvert H-element forbruger det kontekstuelle niveau, sikrer Math.min, at der ikke gives overskrifter på et større niveau end 6. En eller ville ikke blive fortolket som en overskrift af browseren, hvilket forårsager parsning og - derfor - mangler ved tilgængelighed.

Bortset fra aktiveringen (og React!) Kan vi nu strukturere noget meget tæt på det TimBL oprindeligt forestillede sig:

funktion Dokument (rekvisitter) {
  Vend tilbage (
    
      

Automatisering af overskriftdybde

      <§>          Niveau 2          Søsken niveau 2         <§>            Niveau 3                        Niveau 2       

Lorem ipsum dolor sit osv.

       ); }

Enhver komponent, der bruger Level.Provider og Level.Consumer kan laves til at respektere den kontekstbevidste kontur. For komponenter, der indpakker indhold, men ikke kan betragtes som semantiske underafsnit, kan niveauet bare passeres og genbruges som det er - ikke forøget.

Styling

Hvordan du anvender stylingen afhænger af din strategi. I de fleste tilfælde skal overskriftets skriftstørrelse afspejle dens placering i hierarkiet med

som den største eller mest fremtrædende.

Brug af kontekst gøres dette automatisk ved at gengive de forskellige overskriftelementer. Ved hjælp af aria-niveau teknik, skal du parre elementerne og attributterne i henhold til niveau:

h1, [aria-level = "1"] {font-size: 3rem}
h2, [aria-level = "2"] {font-size: 2.25rem}
h3, [aria-level = "3"] {font-size: 1.75rem}
/* etc */

Hvor du ønsker, at det visuelle udseende af komponentens overskrift ikke påvirkes af kontekst, mens du stadig opretholder et tilgængeligt hierarki, kan du muligvis anvende en klasse.

 Overskriftstekst 

Ved hjælp af et bibliotek som Stylede komponenter vil du oprette nye overskrifter baseret på den semantiske H-komponent og style dem direkte. Du skal bare forlænge H:

const Overskrift = H.extend`
  skriftstørrelse: 2rem;
`;

Overskrifter betyder stadig noget

Nogle webapplikationsudviklere har en vane med at undgå alt, hvad de betragter ”fra en æra med enkle dokumenter”. Det er sandt, at overskrifter har oprindelse i en tradition for at markere statiske, prosaiske dokumenter som dem, du måske skriver i MS Word eller lignende. Men at tro, at en lydrubrikstruktur ikke er nødvendig i en applikationsgrænseflade, er at forkert forstå, hvad overskrifter virkelig er.

Overskrifter er etiketter til sektioner (eller 'områder', hvis du foretrækker det), der udgør en grænseflade. De kan mærke et afsnit af information eller et sæt interaktive kontroller. Det er det samme. Mærkning af sektionerne i din interface er lige så vigtig som mærkning af dine individuelle kontroller. Uden etiketter ved folk simpelthen ikke, hvad noget er til.

For brugere af skærmlæser er overskrifter ikke kun etiketter, men en 'bypass'-mekanisme, der giver dem mulighed for at navigere mellem forskellige områder. Uden overskrifter er de nødt til at gå gennem hvert enkelt element efter tur for at komme fra et sted til et andet. Svær og afskrækkende.

Tastaturbrugere, der ikke kører en skærmlæser, der understøtter disse genveje, kan muligvis finde deres oplevelse temmelig besværlig - især hvor der er et stort antal interaktive kontroller, der skal gennemgå. Heldigvis er en browserudvidelse fra Matt Atkinson tilgængelig for at hjælpe. Det giver genveje til ikke overskrifter, men landemærkeelementer (

,
,
osv.), Men support til overskrifter overvejes også. De bedste dokument (og anvendelse!) Strukturer inkluderer både vartegn og overskrifter. Bælte og seler.

For mere om inkluderende design og designsystemer, se https://inclusive-components.design/ og følg Inclusive Components på Twitter.