Tabpaneel

Tabs zijn een set gelaagde inhoudssecties. Je toont één inhoudspaneel tegelijk. Elk paneel heeft een bijbehorend tab-element. Als je een tab activeert, zie je het bijbehorende paneel. De lijst met tab-elementen staat meestal aan de bovenkant van het zichtbare paneel.

Gebruik een tabpaneel:

  • Bij lange pagina’s met veel informatie (FAQ’s, handleidingen)
  • Om gebruikers te laten kiezen welke content ze willen zien

Belangrijke termen:

  • Container: Dit is het element waar het tabpaneel in is opgebouwd.
  • Tab: Een element in de tab list. Dit werkt als label voor een paneel. Je activeert het om het paneel te tonen.
  • Paneel: Het element met de inhoud die bij een tab hoort.

Technische opbouw

  • Maak de container op met role="tablist"
  • Geef elke tab de rol tab (role="tab")
  • Geef elke tab een naam (via zichtbare tekst)
  • Geef elke tab een uniek ID
  • (Plaats alle tabs binnen het element met rol tablist)
  • Geef elk paneel de rol tabpanel (role="tabpanel")
  • Geef elk paneel een naam (via aria-labelledby, gebruik het ID van de bijbehorende tab
  • Geef elk paneel een uniek ID
  • Koppel de tabs en panelen via aria-controls, gebruik het ID van het bijbehorende paneel
  • Voor actieve tabs:
    • Geef de tab de waarde aria-selected="true"
  • Voor inactieve tabs:
    • Geef de tabs de waarde aria-selected="false"
    • Verberg het bijbehorende paneel met hidden

Optionele verbeteringen

  • Geef de container een naam
  • Staan de tabs verticaal? Voeg dan aria-orientation="vertical" toe (standaard is horizontaal)

Voorbeeld tabpaneel

HTML
<!-- Tabpaneel code -->
<div class="tabs">
  <ul class="tab-list" role="tablist" aria-label="Productinformatie">
    <li role="presentation">
      <button class="tab" role="tab" aria-selected="true" aria-controls="tab-panel-1" id="tab-1" tabindex="0">
        Beschrijving
      </button>
    </li>
    <li role="presentation">
      <button class="tab" role="tab" aria-selected="false" aria-controls="tab-panel-2" id="tab-2" tabindex="-1">
        Specificaties
      </button>
    </li>
    <li role="presentation">
      <button class="tab" role="tab" aria-selected="false" aria-controls="tab-panel-3" id="tab-3" tabindex="-1">
        Reviews
      </button>
    </li>
  </ul>
</div>
<div class="tab-panel active" role="tabpanel" id="tab-panel-1" aria-labelledby="tab-1">
  <h3>
    Productbeschrijving
  </h3>
  <p>
    Dit product biedt uitstekende kwaliteit en functionaliteit.
  </p>
</div>
<div class="tab-panel" role="tabpanel" id="tab-panel-2" aria-labelledby="tab-2">
  <h3>
    Technische specificaties
  </h3>
  <p>
    Afmetingen: 30x20x10 cm, Gewicht: 2kg, Materiaal: Duurzaam plastic
  </p>
</div>
<div class="tab-panel" role="tabpanel" id="tab-panel-3" aria-labelledby="tab-3">
  <h3>
    Klantreviews
  </h3>
  <p>
    Gemiddelde beoordeling: 4.5/5 sterren gebaseerd op 127 reviews.
  </p>
</div>
CSS
/* Tabpaneel stijlen */
.tabs {
  max-width: 800px;
  margin: 0 auto;
}

.tab-list {
  display: flex;
  margin: 0;
  padding: 0;
  list-style: none;
  border-bottom: 2px solid;
}

.tab {
  background: transparent;
  border: none;
  padding: 8px 12px;
  cursor: pointer;
  border-bottom: 2px solid;
  font-size: 1rem;
  color: black;
}

.tab[aria-selected="true"] {
  border-bottom-color: white;
  color: white;
  background: black;
}

.tab:hover {
  background: grey;
  color: white;
}

.tab-panels {
  max-width: 800px;
  margin: 0 auto;
  background: white;
  border: 1px solid;
  border-top: none;
}

.tab-panel {
  padding: 2rem 1rem;
  display: none;
}

.tab-panel.active {
  display: block;
} 
JavaScript
// Tabpaneel functionaliteit
class TabPanel {
  constructor() {
    this.tabs = Array.from(document.querySelectorAll('.tab'));
    this.panels = Array.from(document.querySelectorAll('.tab-panel'));
    this.currentTab = 0;

    this.init();
  }

  init() {
    this.tabs.forEach((tab, index) => {
      tab.addEventListener('click', () => this.activateTab(index));
      tab.addEventListener('keydown', (e) => this.handleKeydown(e, index));
    });
  }

  activateTab(index) {
    this.tabs[this.currentTab].setAttribute('aria-selected', 'false');
    this.tabs[this.currentTab].setAttribute('tabindex', '-1');
    this.panels[this.currentTab].classList.remove('active');

    this.currentTab = index;
    this.tabs[this.currentTab].setAttribute('aria-selected', 'true');
    this.tabs[this.currentTab].setAttribute('tabindex', '0');
    this.panels[this.currentTab].classList.add('active');
    this.tabs[this.currentTab].focus();
  }

  handleKeydown(e, index) {
    switch (e.key) {
      case 'ArrowLeft':
        e.preventDefault();
        const prevIndex = (index - 1 + this.tabs.length) % this.tabs.length;
        this.activateTab(prevIndex);
        break;
      case 'ArrowRight':
        e.preventDefault();
        const nextIndex = (index + 1) % this.tabs.length;
        this.activateTab(nextIndex);
        break;
      case 'Home':
        e.preventDefault();
        this.activateTab(0);
        break;
      case 'End':
        e.preventDefault();
        this.activateTab(this.tabs.length - 1);
        break;
    }
  }
}

new TabPanel();

Toetsenbordbediening

  • Enter of Spatie:
    • Opent de tab (als de tabs niet automatisch openen)
  • Tab:
    • Gaat naar het volgende focusbare element in de tablist (meestal het tabpanel)
  • Pijltjestoetsen (horizontale tabs):
    • Pijl rechts: gaat naar de volgende tab
    • Pijl links: gaat naar de vorige tab
  • Pijltjestoetsen (verticale tabs):
    • Pijl omlaag: gaat naar de volgende tab
    • Pijl omhoog: gaat naar de naar vorige tab

Optionele toetsen

  • Home:
    • Gaat naar eerste tab
  • End:
    • Gaat naar laatste tab

Beoordeling

Component

  • (4.1.2) De container moet de rol tablist hebben (role="tablist")
  • (1.3.1) Alle tabs moeten binnen het tablist element staan
  • (4.1.2) Elke tab moet de rol tab hebben (role="tab")
  • (4.1.2) Elke tab moet een toegankelijke naam hebben
    • (2.4.6) De toegankelijke naam moet beschrijven wat er in het paneel staat
  • (4.1.1) Elke tab moet een uniek ID hebben
  • (1.3.1) Elke tab moet aria-controls hebben met het ID van het bijbehorende paneel
  • (4.1.2) Elk paneel moet de rol tabpanel hebben (role="tabpanel")
  • (4.1.1) Elk paneel moet een uniek ID hebben
  • (4.1.2) Elk paneel moet aria-labelledby hebben met het ID van het bijbehorende tab
  • (4.1.2) De actieve tab moet aria-selected="true" hebben
  • (4.1.2) Inactieve tabs moeten aria-selected="false" hebben
  • (1.3.1) Inactieve panelen moeten verborgen zijn

Bronnen