Kopniveaus beheren in ontwerpsystemen

Een ding dat steeds terugkomt, in onderzoek, testen en dagelijks gesprek met collega's en vrienden, is hoe belangrijk rubrieken zijn. Voor gebruikers van schermlezers beschrijven koppen de relaties tussen secties en subsecties en bieden ze - indien correct gebruikt - zowel een overzicht als een navigatiemiddel. Koppen zijn infrastructuur.

Het juiste koersniveau toepassen is een kwestie van context. Twee opeenvolgende koppen van hetzelfde niveau beschrijven bijvoorbeeld twee broers of zussen in het documentoverzicht. Waar de tweede van de opeenvolgende koppen een hoger niveau is, beschrijft deze een subsectie die behoort tot de sectie van de eerste kop.

alt text = in de afbeelding zijn er twee vakken na elkaar, gemarkeerd als broers en zussen op h2-niveau. In het tweede vak bevindt zich een derde vak gemarkeerd als een subsectie h3-niveau.

HTML5 beloofde deze relaties te automatiseren door het nestalgoritme uit te stellen naar

s (of andere sectie-elementen). Het idee was dat, door de bovenliggende
-elementen letterlijk in het DOM te nesten, hun kopniveau's gratis zouden worden aangepast in de toegankelijkheidsboom. (De toegankelijkheidsboom is de interpretatie van de DOM die wordt gecommuniceerd naar software zoals schermlezers.)

  

Sectiekop

  
     'voor schermlezers ->     

Subsectie kop

  

Helaas heeft tot nu toe geen enkele grote browserfabrikant dit zogenaamde "documentoverzichtalgoritme" zinvol geïmplementeerd. En als de browser het niet onthult, kunnen schermlezers het niet communiceren. Het laatste codevoorbeeld zou gewoon niet werken.

Degenen onder ons die geïnteresseerd zijn in het creëren van toegankelijke documentomtrekken, zitten daarom vast in het kiezen van kopniveaus (

tot

), ongeacht de s die we mogelijk gebruiken.

  

Sectiekop

  
    

Subsectie kop

  

Dit vormt een bijzonder probleem bij het ontwikkelen van patroonbibliotheken voor ontwerpsystemen. Hoewel individuele patronen / componenten binnen een ontwerpsysteem koppen kunnen en moeten gebruiken, is het moeilijk om te weten welke koersniveaus ze moeten nemen. Als geïsoleerde modules binnen een patroonbibliotheek is de context van de component binnen een pagina onbepaald. Voor herbruikbare componenten zal de context veranderen, samen met het vereiste niveau.

alt text = In de afbeelding wordt getoond dat een component herbruikbaar is in verschillende contexten van een pagina. Afhankelijk van de context moet de component een kopniveau h2 of h3 hebben.

Het niveau prop

API's zoals React's en Vue's laten ons handmatig eigenschappen (of ‘rekwisieten’) voor onze componenten bij instantiëring opnemen. Hiermee kunnen we bepaalde instellingen toepassen op de instantie van de component, voor intern gebruik.

Door een level prop te ondersteunen, kunnen we auteurs toestaan ​​om het kopniveau van de component aan te passen op het moment van instantiëren, wanneer ze zich bewust zijn van de omliggende context. Dit is hoe het zou worden toegepast op de buitenste component:

 

Intern moeten we het voorgeschreven niveau nemen en dit gebruiken om de hoofdrubriek van de component te vergroten. Er zijn een aantal manieren om dit te doen. De eerste manier zou zijn om wat logica te gebruiken die voor ons het juiste koerselement (

tot

) kiest. In React kunnen we een component als variabele gebruiken:

render () {
  const H = 'h' + this.props.level;
  terug (
    
       Een kop van een bepaald niveau       

Lorem ipsum etc.

       ); }

Dit wordt snel onhandig bij het handhaven van een structuur van meerdere rubrieken binnen de component (zie de volgende sectie). In plaats daarvan kunnen we het niveau van het kopelement rechtstreeks in de toegankelijkheidsstructuur wijzigen, via de eigenschap aria-level.

Twee dingen om op te merken:

  • Een

    -element wordt gebruikt als een "verstandige standaard". Alle eerstelijnsrubrieken die de hoofdtitel

    van de pagina volgen, zouden van het tweede (

    ) niveau zijn. Wanneer de niveauprop niet wordt opgegeven, wordt aria-niveau niet toegepast en fungeert het impliciete tweede niveau als standaard (de nulwaarde betekent dat het kenmerk niet wordt weergegeven).

  • De

    heeft al de impliciete koprol, dus het gebruik van role = "kop" zou overbodig zijn. Als we een
    hadden gebruikt om onze kop te definiëren, zou role = "kop" nodig zijn naast het aria-niveau. Dit wordt niet aanbevolen, omdat de ondersteuning relatief beperkt is. In ieder geval waar aria-niveau niet wordt ondersteund, hebben we nog steeds een

    kop - zelfs als dit niet het juiste niveau is. Koppen, van elk niveau, kunnen worden genavigeerd tussen schermlezers zoals NVDA of JAWS met behulp van de h-toets.

Meerdere rubrieken

In sommige gevallen kan de substructuur waaruit onze component bestaat, meerdere koppen bevatten die een microstructuur in het document beschrijven. Hard coderen van elk niveau via zijn eigen prop zou uitgebreid zijn en vatbaar voor fouten van de kant van de auteur.


 

In plaats daarvan kunnen we dezelfde structuur behouden door wat eenvoudige rekenkunde toe te passen.

Richtingstekst

Lorem ipsum.

Tekst ondertitel

Lorem ipsum.

Geneste subtitel

Lorem ipsum.

Nu hoeft de auteur nog steeds slechts één niveau toe te passen op het moment van instantiëren (indien nodig!) En de hele structuur verandert dienovereenkomstig. Simpel maar effectief.

Volledige automatisering

Wist je dat een -element oorspronkelijk al in 1991 aan de orde werd gesteld en koppenniveaus zou automatiseren zoals het legendarische "Document Outline Algorithm" zou moeten doen? In feite wordt het nog steeds besproken.

Zoals de eminente Sophie Alpert mij heeft aangetoond, is het mogelijk om dit geautomatiseerde overzichtsgedrag te emuleren met behulp van de relatief nieuwe Context API van React.

Het mooie van Context is dat je - om de documenten te citeren - "gegevens door de componentenboom kunt laten gaan zonder dat je rekwisieten op elk niveau handmatig moet opgeven". In de praktijk betekent dit dat we de waarde van het niveau eenvoudig kunnen aanpassen door componenten te nesten.

Eerst moeten we de context initialiseren.

const Level = React.createContext (2);

Let op de 2 die het standaardniveau instelt, zoals in vorige voorbeelden. Nu moeten we alleen de componenten Section en H instellen.

functie sectie (rekwisieten) {
  terug (
     {level =>
      
        {} Props.children
      
    } 
  );
}
functie H (rekwisieten) {
  terug (
     {level => {
      const Heading = 'h' + Math.min (level, 6);
      retourneer ;
    }} 
  );
}

De sectie verbruikt de niveauwaarde voor dat nestniveau (via Level.Consumer) en past vervolgens het niveau voor eventuele kinderen aan (niveau + 1).

Waar een H-element het contextuele niveau verbruikt, zorgt Math.min ervoor dat er geen koppen met een hoger niveau dan 6 worden weergegeven. Een of zou door de browser niet als een kop worden geïnterpreteerd, waardoor parsing en - daardoor - tekortkomingen in de toegankelijkheid ontstaan.

Afgezien van de hoofdletters (en React!) Kunnen we nu iets structureren dat heel dicht in de buurt komt van wat TimBL oorspronkelijk dacht:

functie Document (rekwisieten) {
  terug (
    
      

Kopdiepte automatiseren

      
         Niveau 2          Broer / zus niveau 2         
           Niveau 3                        Niveau 2       

Lorem ipsum dolor sit etc.

       ); }

Elk onderdeel dat Level.Provider en Level.Consumer gebruikt, kan worden gemaakt om de contextbewuste omtrek te respecteren. Voor componenten die inhoud verpakken maar niet als semantische subsecties kunnen worden beschouwd, kan het niveau gewoon worden doorgegeven en opnieuw worden gebruikt zoals het is - niet verhoogd.

styling

Hoe u de styling toepast, hangt af van uw strategie. In de meeste gevallen moet de lettergrootte van de kop de positie in de hiërarchie weergeven, met de

als de grootste of meest prominente.

Met Context gebeurt dit automatisch door de verschillende kopelementen weer te geven. Met behulp van de aria-niveau techniek, zou je de elementen en attributen volgens niveau moeten koppelen:

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

Waar u wilt dat de visuele weergave van de kop van het onderdeel niet wordt beïnvloed door de context, terwijl u toch een toegankelijke hiërarchie behoudt, kunt u een klasse toepassen.

 Titel van tekst 

Met behulp van een bibliotheek zoals Styled Components, zou u nieuwe koppen maken op basis van de semantische H-component en deze rechtstreeks opmaken. Je hoeft alleen H uit te breiden:

const Heading = H.extend`
  lettergrootte: 2rem;
`;

Koppen doen er nog steeds toe

Sommige ontwikkelaars van webapplicaties hebben de gewoonte om af te zien van alles wat ze beschouwen "uit een tijdperk van eenvoudige documenten". Het is waar dat koppen voortkomen uit een traditie van het markeren van statische, prozaïsche documenten zoals die u zou kunnen schrijven in MS Word of iets dergelijks. Maar denken dat een goede kopstructuur niet nodig is in een applicatie-interface, is verkeerd begrijpen wat koppen eigenlijk zijn.

Koppen zijn labels voor secties (of 'gebieden' als u dat wilt) die een interface vormen. Ze kunnen een gedeelte met informatie of een reeks interactieve bedieningselementen labelen. Het is allemaal hetzelfde. Het labelen van de delen van uw interface is net zo belangrijk als het labelen van uw individuele bedieningselementen. Zonder labels weten mensen gewoon niet waar iets voor is.

Voor gebruikers van schermlezers zijn koppen niet alleen labels, maar een 'bypass'-mechanisme waarmee ze tussen verschillende gebieden kunnen navigeren. Zonder koppen moeten ze achtereenvolgens door elk afzonderlijk element stappen om van de ene plaats naar de andere te komen. Moeilijk en onaangenaam.

Toetsenbordgebruikers die geen schermlezer gebruiken die deze snelkoppelingen ondersteunt, kunnen hun ervaring behoorlijk moeizaam vinden - vooral wanneer er een groot aantal interactieve bedieningselementen is om doorheen te stappen. Gelukkig is een browserextensie van Matt Atkinson beschikbaar om te helpen. Het biedt snelkoppelingen niet naar koppen, maar landmark-elementen (

,
,
enz.) Maar ondersteuning voor koppen wordt ook overwogen. De beste document (en applicatie!) Structuren omvatten zowel oriëntatiepunten als koppen. Riem en bretels.

Voor meer informatie over inclusief ontwerp en ontwerpsystemen, zie https://inclusive-components.design/ en volg Inclusive Components op Twitter.