JavaScript/Tutorials/zugängliche Registerkarten

Aus SELFHTML-Wiki
Wechseln zu: Navigation, Suche
Beachten Sie: Das nachfolge Tutorial bedarf einer Überarbeitung. Es ist in der derzeitigen Form nicht verwendbar, denn die Tabs sind nicht für alle Nutzer zugänglich. Wie man zugängliche Registerkarten implementiert, erfahren Sie in diesem englischen Artikel: Inclusive Components: Tabbed Interfaces


Unter dynamischen Tabs (engl. Tabbed interfaces oder Tab Panels) versteht man das Präsentieren von Inhalten in Registerkarten. Reiter wie in einer Hängeregistratur verweisen auf die vorhandenen Registerkarten. Da nur die ausgewählte Registerkarte angezeigt wird, ist dies eine platzsparende, übersichtliche und visuell intuitive Art Inhalte zu präsentieren.


Allerdings können nicht alle Benutzer die visuellen Hinweise interpretieren und mit Maus oder Geste ansteuern. In diesem Tutorial zeigen wir Ihnen, wie Sie Tabs erstellen, die auch mit der Tastatur bedient werden können.

HTML-Grundgerüst

Grundgerüst
<div id="tabpanel">
  <ul role="tablist" id="tablist">
    <li id="link1" role="tab" aria-controls="panel-1">1 - Button</li>
    <li id="link2" role="tab" aria-controls="panel-2">2 - Button</li>
    <li id="link3" role="tab" aria-controls="panel-3">3 - Button</li>
  </ul>
 
  <div id="tabcontent">
    <div id="panel-1" role="tabpanel" aria-labelledby="link1">
      <h3>Inhalt 1</h3>
      <p> Hier kommt was hin!</p>
    </div>
    <div id="panel-2" role="tabpanel" aria-labelledby="link2">
    <h3>Inhalt 1</h3>
      <p> Hier kommt was hin!</p>
    </div>
    <div id="panel-3" role="tabpanel" aria-labelledby="link3">
      <h3>Inhalt 1</h3>
      <p> Hier kommt was hin!</p>
    </div>
  </div>
</div>  
</section>
Unser Tab Panel besteht aus einer Navigation in Form einer Liste und einem div mit drei Kindelementen, die über das aria-labelledby-Attribut mit der id der Buttons verbunden sind. Deren aria-controls-Attribut zielt auf die id der Listenelemente.
Beachten Sie: Im Unterschied zu anderen Beispielen im Web werden hier keine a-Elemente für die Navigation verwendet, da es sich um eine interne Funktionalität des widgets und keinen externen Link auf eine URL handelt.

ARIA-Zustände

Aria-Attribute beschreiben einerseits Rollen von sowie Beziehungen zwischen Elementen. Darüber hinaus können mit ihnen auch Live Regions in ihren jeweiligen Zuständen näher beschreiben werden.

Details: caniuse.com

Elemente, die Aussehen und Darstellung ändern, haben im Allgemeinen Zustände, die durch Benutzeraktionen geändert werden. So ändern die einzelnen Tabs ihren Zustand von „nicht ausgewählt“ auf „ausgewählt“, wenn sie geklickt werden und werden plötzlich sichtbar.

Dies kann mit den Aria-Attributen aria-selected und aria-hidden ausgezeichnet und durch CSS-Selektoren sichtbar gemacht werden:

ARAI-Zustände als Selektoren für das CSS
#tablist li[aria-selected="true"] {
  background-color: white;
  padding: 0.5em 0.5em 11px;  
}

div[aria-hidden="true"] {
display: none;
}
Beachten Sie: ARIA-Attribute können ab IE10 über das CSS selektiert werden. Wenn Sie ältere Versionen unterstützen müssen, können Sie anstelle von aria-hidden='true' eine Klasse hidden einsetzen.

Auch das HTML wird angepasst:

Grundgerüst mit ARIA-Zuständen
<div id="tabpanel">
  <ul role="tablist" id="tablist">
    <li id="link1" role="tab" aria-controls="panel-1" aria-selected="true">1 - Button</li>
    <li id="link2" role="tab" aria-controls="panel-2" aria-selected="false">2 - Button</li>
    <li id="link3" role="tab" aria-controls="panel-3" aria-selected="false">3 - Button</li>
  </ul>
 
  <div id="tabcontent">
    <div id="panel-1" role="tabpanel" aria-labelledby="link1" aria-hidden="false">
      <h3>Inhalt 1</h3>
      <p> Hier kommt was hin!</p>
    </div>
    <div id="panel-2" role="tabpanel" aria-labelledby="link2" aria-hidden="true">
    <h3>Inhalt 1</h3>
      <p> Hier kommt was hin!</p>
    </div>
    <div id="panel-3" role="tabpanel" aria-labelledby="link3" aria-hidden="true">
      <h3>Inhalt 1</h3>
      <p> Hier kommt was hin!</p>
    </div>
  </div>
</div>
Der erste Button erhält das ARIA-Attribut aria-selected="true" und sein entsprechendes Panel aria-hidden="false", sodass es sichtbar ist.
Die anderen Buttons werden mit aria-selected="false" ausgezeichnet und ihr dazugehörendes Panel mit aria-hidden="true" unsichtbar versteckt.

CSS

Nun wird es Zeit, das Tab Panel mit dem gewünschten CSS zu gestalten.

Grundgerüst mit ARIA-Zuständen als CSS-Selektoren ansehen …
#tablist {
  list-style: none;
  margin: 0;
  padding: 0;
}

#tablist li {
  background-color: lightgrey;	
  border: 1px solid black;
  border-bottom: none;
  border-radius: 0.5em 0.5em 0 0;
  display: inline;
  font-weight: bold;
  height: 1em;
  padding: 0.5em 0.5em 10px;
}

#tablist li:focus, 
#tablist li:hover {
  background-color: yellow;
}

#tablist li[aria-selected="true"] {
  background-color: white;
  padding: 0.5em 0.5em 11px;  
}

#tabcontent {
  background-color: white;
  border: 1px solid black; 
  margin-top: 10px;
  padding: 1em;
}

[aria-hidden="true"] {
  display: none;
}
 
[aria-hidden="false"] {
  display: block;
}
Die Listenelemente, die als Steuerungselemente dienen, haben keine Klassen und werden nur über die ARIA-Zustände selektiert.

Funktionalität

Bis jetzt bestehen die Steuerungselement nur aus funktionslosen Listenelementen. In den folgenden Schritten wird mit JavaScript die Möglichkeit zur Benutzerinteraktion hinzugefügt.

Änderungen des Zustands

Bei einem Klick auf die Steuerungselemente soll das dazugehörende Panel eingeblendet werden:

Beispiel ansehen …
    function init() {     
      var tab = document.getElementById('tablist');
      tab.addEventListener('click',clickHandler);
    }

    function clickHandler(elem) {
      var target = elem.target; 

      if (target.parentNode.id != 'tablist') return false;

      var selectedTab = document.querySelector('[aria-selected="true"]');
      selectedTab.setAttribute('aria-selected', false);
      target.setAttribute('aria-selected', true);

      var panels = document.querySelector('[aria-hidden="false"]');
      panels.setAttribute('aria-hidden', true);
	  
      var panelId =target.getAttribute('aria-controls'),
	  panel = document.getElementById(panelId);  
      panel.setAttribute('aria-hidden', false);
    }
In der Funktion init() wird ein EventHandler für das gesamte Tab Panel angehängt.

Durch einen Klick wird die Funktion clickHandler() aufgerufen, die mit event.Target das geklickte Tab identifiziert.

Durch if (target.parentNode.id != 'tablist') return false; werden alle Klicks, welche sich nicht auf einen Tab der "tablist" beziehen herausgefiltert.

Bevor der Zustand dieses Tab nun auf aria-selected="true" geändert wird, wird mit querySelector das bisher ausgewählte Tab gesucht und auf aria-selected="false" gesetzt.

Analog wird mit den Panels verfahren. Da der Wert des aria-controls-Attributs der id des dazugehörenden Panels entspricht, kann es über die Variable panelId ausgewählt und dann auf aria-hidden="false"gesetzt werden.

Änderungen des focus

Um die einzelnen Steuerungselemente mit der Tab-Taste ( ) „durchtabben“ zu können, müssen wir den li-Elementen einen tabindex mitgeben. Mit diesem Universalattribut können Sie das Steuerungselement nun auch mit der Tastatur bedienen:

Beispiel
  <ul role="tablist" id="tablist">
    <li id="link1" role="tab" aria-controls="panel-1" aria-selected="true" tabindex="0">1 - Button</li>
    <li id="link2" role="tab" aria-controls="panel-2" aria-selected="false" tabindex="0">2 - Button</li>
    <li id="link3" role="tab" aria-controls="panel-3" aria-selected="false" tabindex="0">3 - Button</li>
  </ul>
durch das Universalattribut tabindex="0" wird unser kleines Menü zugänglich für Tastatureingaben. Allerdings reagiert es noch nicht auf die Eingabe der Enter-Taste ().

Tastatureingabe

Nun benötigen wir zum Abschluss noch eine Funktion, die bei Tastatureingaben aufgerufen wird und diese verarbeitet.

Beispiel
    function init() {     
      var tab = document.getElementById('tablist');
      tab.addEventListener('click',clickHandler);
      tab.addEventListener('keypress', keyHandler);
    }

    function keyHandler(elem) {

    }
In der Funktion init() wird ein weiterer EventHandler angehängt, der über den keypress-Event ausgelöst wird. Durch eine Tastatureingabe wird die Funktion keyHandler() aufgerufen, die mit event.key die geklickte Taste identifiziert.

Siehe auch


Weblinks

Allgemein:

zugängliche Registerkarten: