Accordion

In Bootstrap v6.0.0 neu aufgebaut

Vertikal auf- und zuklappende Bereiche – in Bootstrap 6 komplett auf Basis der nativen HTML-Elemente <details> und <summary>.

Das Accordion gab es schon in Bootstrap 5, dort steuerte das Collapse-JavaScript das Öffnen und Schließen. In Bootstrap 6 übernimmt das der Browser selbst: Über das gemeinsame name-Attribut entstehen exklusive Accordions, bei denen immer nur ein Eintrag offen ist.

  • Kein JavaScript nötig: Die Grundfunktion liefert der Browser.
  • Exklusiv oder frei: Mit gemeinsamem name ist nur ein Eintrag offen, ohne name beliebig viele.
  • Varianten: Themenfarben, kompakte Größe, randlos (flush) und mit Abstand (gap).
  • Barrierefrei: Zustand und Tastaturbedienung bringen die nativen Elemente mit.

Quelle: Bootstrap-Dokumentation (englisch), übersetzt und bearbeitet. Doku lizenziert unter CC BY 3.0.

Beispiel

Jeder Eintrag ist ein <details class="accordion-item">. Haben alle Einträge denselben name, schließt das Öffnen eines Eintrags automatisch die anderen. Soll ein Eintrag beim Laden offen sein, setzt du das Attribut open.

Accordion-Eintrag #1
Das ist der Inhalt des ersten Eintrags. Er ist beim Laden geöffnet, weil das Attribut open gesetzt ist. Das native <details>-Element erledigt das Ein- und Ausblenden ganz ohne JavaScript. In .accordion-body darf beliebiges HTML stehen.
Accordion-Eintrag #2
Das ist der Inhalt des zweiten Eintrags. Das Attribut name verbindet ihn mit den anderen Einträgen. Öffnest du ihn, schließt sich jeder andere offene Eintrag derselben Gruppe.
Accordion-Eintrag #3
Das ist der Inhalt des dritten Eintrags. Das exklusive Verhalten steckt im Browser – Bootstrap-JavaScript ist nicht nötig. Verwende einfach gleiche name-Werte an deinen <details>-Elementen.
<div class="accordion">
  <details class="accordion-item" name="accordionExample" open>
    <summary class="accordion-header">
      Accordion-Eintrag #1
      <svg class="accordion-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"><path d="m2 5 6 6 6-6"/></svg>
    </summary>
    <div class="accordion-body">
      <strong>Das ist der Inhalt des ersten Eintrags.</strong> Er ist beim Laden geöffnet, weil das Attribut <code>open</code> gesetzt ist. Das native <code>&lt;details&gt;</code>-Element erledigt das Ein- und Ausblenden ganz ohne JavaScript. In <code>.accordion-body</code> darf beliebiges HTML stehen.
    </div>
  </details>
  <details class="accordion-item" name="accordionExample">
    <summary class="accordion-header">
      Accordion-Eintrag #2
      <svg class="accordion-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"><path d="m2 5 6 6 6-6"/></svg>
    </summary>
    <div class="accordion-body">
      <strong>Das ist der Inhalt des zweiten Eintrags.</strong> Das Attribut <code>name</code> verbindet ihn mit den anderen Einträgen. Öffnest du ihn, schließt sich jeder andere offene Eintrag derselben Gruppe.
    </div>
  </details>
  <details class="accordion-item" name="accordionExample">
    <summary class="accordion-header">
      Accordion-Eintrag #3
      <svg class="accordion-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"><path d="m2 5 6 6 6-6"/></svg>
    </summary>
    <div class="accordion-body">
      <strong>Das ist der Inhalt des dritten Eintrags.</strong> Das exklusive Verhalten steckt im Browser – Bootstrap-JavaScript ist nicht nötig. Verwende einfach gleiche <code>name</code>-Werte an deinen <code>&lt;details&gt;</code>-Elementen.
    </div>
  </details>
</div>

Die Höhenanimation des Panels braucht interpolate-size. Browser ohne diese Eigenschaft klappen das Panel ohne Übergang auf und zu. Timing ändern oder Animation abschalten: siehe Transitions. Bei aktivierter Einstellung „Bewegung reduzieren“ (prefers-reduced-motion) entfällt die Animation.

Varianten

Mit den Klassen .theme-{farbe} färbst du geöffnete Einträge in einer semantischen Themenfarbe ein.

Accordion-Eintrag #1
Inhalt des ersten Eintrags. Geöffnete Einträge erscheinen in der Themenfarbe primary.
Accordion-Eintrag #2
Inhalt des zweiten Eintrags. Öffnest du ihn, schließt sich der erste.
Accordion-Eintrag #3
Inhalt des dritten Eintrags. Alles ohne Bootstrap-JavaScript.
<div class="accordion theme-primary">
  <!-- Accordion-Einträge -->
</div>

Klein

.accordion-sm am .accordion sorgt für eine kompakte Darstellung mit weniger Innenabstand, kleinerem Radius und kleinerer Schrift.

Accordion-Eintrag #1
Inhalt des ersten Eintrags..accordion-sm verringert Innenabstand, Radius und Schriftgröße.
Accordion-Eintrag #2
Inhalt des zweiten Eintrags. Die kompakten Maße lassen sich über CSS-Variablen feinjustieren.
Accordion-Eintrag #3
Inhalt des dritten Eintrags. Kombinierbar mit Varianten wie .accordion-flush.
<div class="accordion accordion-sm">
  <!-- Accordion-Einträge -->
</div>

Randlos (Flush)

.accordion-flush entfernt einen Teil der Ränder und die abgerundeten Ecken, sodass das Accordion bündig mit seinem Elternelement abschließt.

Accordion-Eintrag #1
Platzhalterinhalt zur Demonstration der Klasse .accordion-flush. Das ist der erste Eintrag.
Accordion-Eintrag #2
Platzhalterinhalt zur Demonstration der Klasse .accordion-flush. Das ist der zweite Eintrag – stell dir hier echten Inhalt vor.
Accordion-Eintrag #3
Platzhalterinhalt zur Demonstration der Klasse .accordion-flush. Das ist der dritte Eintrag. Hier passiert inhaltlich nichts Aufregendes, der Text füllt nur den Platz, damit es auf den ersten Blick halbwegs realistisch aussieht.
<div class="accordion accordion-flush">
  <!-- Accordion-Einträge -->
</div>

Abstand (Gap)

Mit .accordion-gap bekommen die Einträge Abstand zueinander und erscheinen jeweils als eigene, abgerundete Karte. Der Abstand hängt am Accordion, nicht am Panel – das Panel animiert weiterhin nur seine block-size, der Übergang bleibt also flüssig.

Accordion-Eintrag #1
Inhalt des ersten Eintrags..accordion-gap rückt die Einträge auseinander. Jeder behält beim Öffnen und Schließen seinen vollen Radius.
Accordion-Eintrag #2
Inhalt des zweiten Eintrags. Der Abstand bleibt während der Animation gleich, benachbarte Einträge springen nicht.
Accordion-Eintrag #3
Inhalt des dritten Eintrags. Über --accordion-gap änderst du den Abstand.
<div class="accordion accordion-gap">
  <!-- Accordion-Einträge -->
</div>

Immer offen

Lässt du das Attribut name an den <details>-Elementen weg, arbeiten die Einträge unabhängig voneinander und können gleichzeitig geöffnet sein.

Accordion-Eintrag #1
Inhalt des ersten Eintrags. Ohne name arbeitet jeder Eintrag für sich. Du kannst mehrere gleichzeitig öffnen.
Accordion-Eintrag #2
Inhalt des zweiten Eintrags. Das Öffnen schließt den ersten Eintrag nicht, weil kein name sie verbindet.
Accordion-Eintrag #3
Inhalt des dritten Eintrags. Öffne und schließe die Einträge in beliebiger Kombination.
<div class="accordion">
  <details class="accordion-item" open>
    <!-- Kein name-Attribut, Einträge öffnen unabhängig -->
  </details>
  <!-- Weitere Accordion-Einträge -->
</div>

Alle öffnen und schließen

Damit alle Einträge auf einmal aufgehen können, entfernst du per JavaScript das name-Attribut von jedem <details>. Beim Zuklappen setzt du es wieder, wenn das exklusive Verhalten zurückkommen soll.

Accordion-Eintrag #1
Inhalt des ersten Eintrags. „Alle öffnen“ klappt jeden Eintrag auf, auch wenn sie sich einen name teilen.
Accordion-Eintrag #2
Inhalt des zweiten Eintrags. „Alle schließen“ klappt alles zu und stellt die exklusive name-Gruppe wieder her.
Accordion-Eintrag #3
Inhalt des dritten Eintrags. Hat dein Accordion keinen name, reicht es, an jedem Eintrag open zu setzen.
<button type="button" class="btn-subtle btn-sm theme-secondary mb-3" id="btnAccordionToggleAll" aria-expanded="false">Alle öffnen</button>

<div class="accordion accordion-sm" id="accordionExpandCollapse">
  <details class="accordion-item" name="accordionExpandCollapse" open>
    <!-- … -->
  </details>
  <details class="accordion-item" name="accordionExpandCollapse">
    <!-- … -->
  </details>
  <details class="accordion-item" name="accordionExpandCollapse">
    <!-- … -->
  </details>
</div>

Für die Demo kommt dieses JavaScript zum Einsatz:

const accordion = document.getElementById('accordionExpandCollapse')
const toggleBtn = document.getElementById('btnAccordionToggleAll')

if (accordion && toggleBtn) {
  const items = accordion.querySelectorAll('.accordion-item')
  const groupName = 'accordionExpandCollapse'

  toggleBtn.addEventListener('click', () => {
    const expand = toggleBtn.getAttribute('aria-expanded') !== 'true'

    for (const item of items) {
      if (expand) {
        item.removeAttribute('name')
        item.open = true
      } else {
        item.open = false
        item.setAttribute('name', groupName)
      }
    }

    toggleBtn.setAttribute('aria-expanded', String(expand))
    toggleBtn.textContent = expand ? 'Collapse all' : 'Expand all'
  })
}

Verschachtelt

Ein komplettes .accordion lässt sich in ein .accordion-body setzen. Gib jeder Ebene einen eigenen name-Wert, damit äußeres und inneres Accordion unabhängig voneinander arbeiten.

Accordion-Eintrag #1
Inhalt des ersten Eintrags. Darunter steckt ein verschachteltes Accordion.
Innerer Eintrag #1
Inhalt des ersten inneren Eintrags.
Innerer Eintrag #2
Inhalt des zweiten inneren Eintrags.
Innerer Eintrag #3
Inhalt des dritten inneren Eintrags.
Accordion-Eintrag #2
Inhalt des zweiten Eintrags. Hier ist nichts verschachtelt.
Accordion-Eintrag #3
Inhalt des dritten Eintrags. Hier ist nichts verschachtelt.
<div class="accordion">
  <details class="accordion-item" name="accordionNested" open>
    <summary class="accordion-header">
      Accordion-Eintrag #1
      <svg class="accordion-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"><path d="m2 5 6 6 6-6"/></svg>
    </summary>
    <div class="accordion-body">
      <strong>Inhalt des ersten Eintrags.</strong> Darunter steckt ein verschachteltes Accordion.
      <div class="accordion mt-3">
        <details class="accordion-item" name="accordionNestedInner" open>
          <summary class="accordion-header">
            Innerer Eintrag #1
            <svg class="accordion-icon" …>…</svg>
          </summary>
          <div class="accordion-body">
            Inhalt des ersten inneren Eintrags.
          </div>
        </details>
        <!-- Weitere innere Einträge mit name="accordionNestedInner" -->
      </div>
    </div>
  </details>
  <!-- Weitere äußere Einträge mit name="accordionNested" -->
</div>

Anpassen

Eigene Icons

Der Pfeil ist ein Inline-SVG im .accordion-header. Tausche das SVG aus, um ein anderes Icon zu verwenden. Die Klasse .accordion-icon kümmert sich um Position und Drehung beim Öffnen.

<summary class="accordion-header">
  Accordion Title
  <svg class="accordion-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round">
    <path d="m2 5 6 6 6-6"/>
  </svg>
</summary>

Events

Auf das native toggle-Event der <details>-Elemente kannst du direkt reagieren.

const accordionItem = document.querySelector('.accordion-item')
accordionItem.addEventListener('toggle', event => {
  if (event.target.open) {
    console.log('Accordion opened')
  } else {
    console.log('Accordion closed')
  }
})

Steuerung per JavaScript

Über die Eigenschaft open öffnest, schließt oder wechselst du einen Eintrag im Skript.

const accordionItem = document.querySelector('.accordion-item')

// Open the accordion
accordionItem.open = true

// Close the accordion
accordionItem.open = false

// Toggle the accordion
accordionItem.open = !accordionItem.open

CSS-Variablen und Sass-Tokens findest du in der Originaldokumentation.

Barrierefreiheit

Die nativen Elemente <details> und <summary> bringen die nötige Semantik bereits mit:

  • Screenreader kündigen den Zustand (geöffnet/geschlossen) automatisch an.
  • Die Tastaturbedienung funktioniert ohne Zusatzaufwand – Enter oder Leertaste klappt um.
  • <summary> ist von Haus aus fokussierbar.
  • ARIA-Attribute sind nicht erforderlich.