Zum Inhalt springen
Animation

Akkordeons ohne JavaScript mit details animieren

Wie details und summary ein Akkordeon ohne Skript tragen, wie name immer nur einen Eintrag offen lässt, wie ::details-content und interpolate-size die Höhe auf auto animieren und was Firefox und Safari davon bisher zeigen.

9 Min. LesezeitVon Amelie RoesmannStand: 09. November 2026
AnimationHTMLCSSAkkordeon

Ein Akkordeon ist in den meisten Projekten eine kleine Zustandsmaschine: ein Button mit aria-expanded, ein Zustand für den offenen Eintrag und eine Bibliothek, die die Höhe misst, damit sich der Inhalt weich öffnet. Das details-Element kann das meiste davon selbst, seit 2020 in allen großen Browsern. Drei neuere Bausteine schließen den Rest. Das Attribut name lässt in einer Gruppe nur einen Eintrag offen, Baseline seit September 2024. Das Pseudo-Element ::details-content macht den Inhaltsbereich gestaltbar, Baseline seit September 2025. Und interpolate-size erlaubt Übergänge auf height: auto, bisher nur in Chrome und Edge ab Version 129. Dieser Beitrag baut daraus ein Akkordeon ohne Skript, zeigt die Fassung für Tailwind und sagt, was Firefox und Safari heute davon sehen.

Das Wichtigste in Kürze
  • details und summary bringen Fokus, Enter und Leertaste, den Zustand offen oder geschlossen und die Suche im geschlossenen Inhalt mit. Ein eigener Button mit aria-expanded muss das alles nachbauen.
  • Mehrere details mit demselben name bilden eine Gruppe, in der höchstens ein Eintrag offen ist. Chrome und Edge können das seit Version 120, Firefox seit 130, Safari seit 17.2.
  • ::details-content trifft den Inhaltsbereich von details, interpolate-size: allow-keywords auf :root macht height: auto animierbar. Zum Schließen gehört content-visibility mit allow-discrete in die Transition.
  • interpolate-size läuft laut MDN-Daten vom November 2026 nur in Chrome und Edge. Firefox und Safari öffnen dasselbe Akkordeon ohne Übergang, aber korrekt, es braucht also keinen Rückfall mit Skript.
01

Warum reicht details für ein Akkordeon?

Weil details das Verhalten schon mitbringt, das ein eigenes Akkordeon mühsam nachbaut. summary ist mit der Tastatur erreichbar, Enter und Leertaste schalten um, und der Zustand offen oder geschlossen geht an Screenreader, ohne dass ein Skript aria-expanded setzt. Das Element läuft seit Januar 2020 in allen großen Browsern.

Ein Vorteil fällt erst auf, wenn er fehlt. Die Suche im Browser findet Text auch in geschlossenen Einträgen und öffnet den passenden. Laut MDN kann Chrome das seit Version 97, Firefox seit 148 und Safari seit 26.2, dort noch mit einem Fehler beim Scrollen zum Treffer. Ein Akkordeon aus div und Button versteckt seinen Inhalt dagegen so, dass die Suche ihn nicht findet oder nicht aufklappt.

Was details lange nicht konnte, war die Gestaltung. Der Inhalt erschien schlagartig, und um ihn weich zu öffnen, musste man ihn in ein eigenes Element packen und die Höhe per Skript messen. Genau das ändern die drei Bausteine in den nächsten Abschnitten.

<details>  <summary>How long does delivery take?</summary>  <p>Two to four working days within the country.</p></details>
Ein Eintrag, ohne Skript. summary ist die Frage, der Rest die Antwort.
Nur Text in summaryEin Link oder Button in summary löst beim Klick zwei Dinge aus: seine eigene Aktion und das Umschalten des Eintrags. Für Screenreader steht er zudem in einem Element, das selbst schon wie ein Knopf funktioniert. Links gehören in die Antwort, nicht in die Frage.
02

Wie bleibt im Akkordeon immer nur ein Eintrag offen?

Mit demselben Wert im Attribut name an allen details der Gruppe. Öffnet jemand einen Eintrag, schließt der Browser den bisher offenen. Chrome und Edge können das seit Version 120, Firefox seit 130 und Safari seit 17.2. Seit September 2024 gilt das Attribut damit als Baseline.

name verhindert nicht, dass alle Einträge geschlossen sind. Ein Klick auf den offenen schließt ihn wie gewohnt. Und stehen zwei Einträge mit open im Markup, bleibt nur einer offen: Im Test mit Chrome 153 war es der erste. Wer einen Eintrag vorab öffnen will, setzt open also an genau einer Stelle.

Ob eine Gruppe überhaupt exklusiv sein sollte, ist eine eigene Frage. In einem FAQ, in dem jemand zwei Antworten vergleichen will, stört es, wenn die erste zuklappt. Bei Einstellungen oder Schritten, die nacheinander kommen, hilft es, weil die Seite kurz bleibt.

<details name="faq" open>  <summary>Can I change my plan later?</summary>  <p>Yes, at the end of each billing period.</p></details><details name="faq">  <summary>Is there a free trial?</summary>  <p>Fourteen days, no card required.</p></details><details name="faq">  <summary>Where is my data stored?</summary>  <p>In data centres within the EU.</p></details>
Drei Einträge, eine Gruppe. Der erste ist beim Laden offen.
03

Was ist ::details-content?

Ein Pseudo-Element für alles in details außer summary. Es lässt sich gestalten wie ein Kasten, mit Höhe, Overflow, Abständen und Übergängen, ohne dass man den Inhalt in ein zusätzliches Element packen muss. Chrome und Edge kennen es seit Version 131, Firefox seit 143 und Safari seit 18.4. Seit September 2025 gilt es als Baseline.

Möglich wurde das, weil Chrome mit Version 131 die Darstellung des Inhaltsbereichs geändert hat: Er ist jetzt ein Block statt eines Elements, das nur seine Kinder durchreicht. Erst damit hat er eine eigene Höhe, die sich setzen und animieren lässt.

Eine Einschränkung gibt es in Safari. Pseudo-Elemente lassen sich dort nicht an ::details-content anhängen, ein ::details-content::before greift also nicht. Wer eine Trennlinie oder einen Verlauf am Inhalt braucht, setzt ihn auf ein Element in der Antwort.

details::details-content {  padding-inline: 1rem;  border-inline-start: 2px solid currentColor;}
Der Inhaltsbereich als eigener Kasten, ohne zusätzliches div.
04

Wie animiert man die Höhe eines details-Elements auf auto?

Mit interpolate-size: allow-keywords auf :root und einem Übergang auf height am ::details-content. Bisher war auto kein Wert, zwischen dem und einer Zahl ein Browser rechnen konnte, deshalb sprang die Höhe. interpolate-size erlaubt genau diese Rechnung. Die Eigenschaft wird vererbt, eine Zeile auf :root reicht also für die ganze Seite.

Für das Öffnen genügt das. Das Schließen braucht einen zweiten Eintrag in der Transition. Ein geschlossenes details versteckt seinen Inhalt über content-visibility, und das geschieht sofort, bevor die Höhe schrumpfen könnte. Steht content-visibility mit allow-discrete in der Transition, wartet der Wechsel bis zum Ende der Dauer, und der Inhalt bleibt sichtbar, solange er zuklappt. allow-discrete läuft seit Chrome 117, Firefox 129 und Safari 17.4.

overflow: clip schneidet den Inhalt während der Bewegung ab. Mit hidden ginge das auch, clip legt aber keinen Scroll-Container an. Im Test mit Chrome 153 öffnete und schloss das Akkordeon so in beide Richtungen weich, auch dann, wenn name den vorher offenen Eintrag zuklappte.

:root {  interpolate-size: allow-keywords;} details::details-content {  height: 0;  overflow: clip;  transition:    height 300ms ease,    content-visibility 300ms ease allow-discrete;} details[open]::details-content {  height: auto;} @media (prefers-reduced-motion: reduce) {  details::details-content {    transition: none;  }}
Öffnen und Schließen mit Bewegung. Reduzierte Bewegung schaltet sie ab.
max-height als Notlösung
  • Die Höhe läuft auf einen geratenen Wert wie 500 Pixel statt auf den Inhalt.
  • Bei kurzen Antworten wirkt das Schließen verzögert, weil erst der leere Teil schrumpft.
  • Ist eine Antwort länger als der Wert, wird sie abgeschnitten.
height: auto mit interpolate-size
  • Die Höhe läuft genau bis zum Inhalt, egal wie lang die Antwort ist.
  • Dauer und Kurve wirken beim Öffnen und Schließen gleich.
  • Kein Wert im Stylesheet, der beim nächsten längeren Text veraltet.
05

Was sehen Firefox und Safari von der Animation?

Ein Akkordeon, das richtig öffnet und schließt, aber ohne Bewegung. Die Browserdaten von MDN führen interpolate-size im November 2026 nur für Chrome und Edge ab Version 129, als experimentell. caniuse zeigt für Firefox bis Version 162 und Safari bis 27.3 keine Unterstützung und kommt im Oktober 2026 auf rund 74 Prozent der weltweiten Nutzung.

Weil beide Browser ::details-content kennen, greifen dort height: 0 und height: auto trotzdem. Nur der Übergang dazwischen fehlt, denn ohne interpolate-size ist auto kein Ziel, auf das sich rechnen lässt. Das Ergebnis ist das gewohnte details, und es braucht keinen Rückfall, der etwas reparieren müsste.

Die Funktion calc-size, mit der sich auto auch ohne die Eigenschaft auf :root animieren ließe, hilft hier nicht weiter. Sie steht in denselben Browsern bereit wie interpolate-size, also ebenfalls nur in Chrome und Edge ab 129.

Bewegung als Zugabe, nicht als VoraussetzungDie Frage ist nicht, ob alle Browser die Animation zeigen, sondern ob ein Browser ohne sie etwas verliert. Bei einem Akkordeon verliert er nichts: Die Antwort steht da, sobald jemand klickt. Eine Bibliothek, die die Höhe misst, lohnt sich erst, wenn die Bewegung selbst etwas erklärt, etwa wenn ein Eintrag Teil einer größeren Animation ist.
06

Wie baut man das Akkordeon mit Tailwind CSS?

Mit der Variante details-content für den Inhaltsbereich, open für den offenen Zustand und einer beliebigen Eigenschaft für interpolate-size. Nachgesehen in Tailwind CSS 4.3.5: details-content: schreibt auf ::details-content, open: trifft details mit dem Attribut open, und transition-discrete setzt transition-behavior: allow-discrete. Eine eigene Klasse für interpolate-size gibt es nicht, die Schreibweise in eckigen Klammern erzeugt sie.

Die Varianten lassen sich verketten. open:details-content:h-auto ergibt die Höhe auto am Inhalt eines offenen details, und weil diese Regel spezifischer ist als details-content:h-0, gewinnt sie ohne Umwege. motion-reduce:details-content:transition-none schaltet die Bewegung bei reduzierter Bewegung ab.

In React bleibt das Akkordeon ohne Zustand. name und open sind gewöhnliche Attribute, und der Browser merkt sich, welcher Eintrag offen ist. Wer den Zustand doch braucht, hört auf das toggle-Ereignis, statt open bei jedem Rendern zu setzen.

/* global.css: :root { interpolate-size: allow-keywords; } */ export function FaqItem({ question, children }) {  return (    <details      name="faq"      className="border-b border-black/10        details-content:h-0 details-content:overflow-clip        open:details-content:h-auto        details-content:transition-[height,content-visibility]        details-content:transition-discrete details-content:duration-300        motion-reduce:details-content:transition-none"    >      <summary className="cursor-pointer py-4 font-medium">{question}</summary>      <div className="pb-4 text-black/70">{children}</div>    </details>  );}
Ein Eintrag als React-Komponente mit Tailwind. Die Zeile für :root gehört ins globale CSS.

Ein Element, drei Attribute aus dem Standard, sechs Klassen. Der Zustand bleibt im Browser.

Teilen
Geschrieben von
Amelie RoesmannCreative Direction

Wir bauen Websites und Web-Apps bei Systra Studios in Münster und legen die Bausteine daraus hier ab. Was in den Beiträgen steht, kommt aus echten Projekten, nicht aus einem Werbeprospekt.

Systra Studios: Webdesign aus Münster

Frage oben, Antwort darunter.
Die FAQ-Bereiche dazu stehen bereit.

FAQ-Bereiche mit Akkordeon, vom Glaskasten über einem Bild bis zur schlichten Liste. Sie öffnen ihre Antworten über einen Button mit aria-expanded und animieren die Höhe mit Framer Motion, also in allen Browsern. Wer ohne Skript auskommen will, stellt die Liste auf details mit name um.

  • Eine Datei je Komponente, als Quelltext im eigenen Projekt.
  • Gebaut mit React, TypeScript und Tailwind CSS v4.
  • Fragen und Antworten stehen als Daten oben in der Datei.
FAQ-Bereiche ansehen
FAQ

Häufige Fragen

Für ein FAQ ja, und meist besser als ein selbst gebautes. summary ist von Haus aus mit der Tastatur erreichbar, Enter und Leertaste öffnen und schließen den Eintrag, und der Zustand offen oder geschlossen wird an Screenreader weitergegeben, ohne dass jemand aria-expanded pflegen muss. Dazu kommt etwas, das eigene Akkordeons fast nie können: Die Suche im Browser findet Text in geschlossenen Einträgen und öffnet sie. Chrome kann das laut MDN seit Version 97, Firefox seit 148 und Safari seit 26.2, dort mit einem bekannten Fehler beim Scrollen zum Treffer. Wichtig bleibt, dass summary nur Text enthält, keine Links oder Buttons, denn ein Klick darauf würde sonst gleichzeitig den Eintrag umschalten. Für Muster, die mehr sind als Frage und Antwort, etwa Reiter mit Pfeiltasten, passt details dagegen nicht.

Nein, Stand November 2026 nicht. Die Browserdaten von MDN führen interpolate-size und die verwandte Funktion calc-size nur für Chrome und Edge ab Version 129, als experimentell. caniuse zeigt für Firefox bis Version 162 und Safari bis 27.3 keine Unterstützung und kommt im Oktober 2026 auf rund 74 Prozent der weltweiten Nutzung. Das ist weniger schlimm, als es klingt: Ein Browser, der die Eigenschaft nicht kennt, überspringt die Deklaration, und der Übergang auf auto findet dann nicht statt. Das Akkordeon öffnet und schließt trotzdem richtig, nur ohne Bewegung. Wer dieselbe Bewegung in allen Browsern braucht, kommt um JavaScript nicht herum, etwa um eine Bibliothek, die die Höhe misst.

Nein. name sorgt nur dafür, dass höchstens ein Eintrag der Gruppe offen ist. Ein Klick auf den offenen Eintrag schließt ihn, und danach ist keiner mehr offen. Im Test mit Chrome 153 war das genau so, und auch zwei Einträge mit open im Markup ließ der Browser nicht stehen: offen blieb nur der erste. Wer immer genau einen offenen Eintrag braucht, baut eigentlich Reiter und keine Akkordeons, und Reiter brauchen eigene Rollen und Pfeiltasten, also Skript. Für ein FAQ ist der Zustand, in dem alles zu ist, ohnehin in Ordnung, denn die Liste der Fragen ist dann am kürzesten.

Für ein FAQ in Chrome und Edge nicht, für dieselbe Bewegung in allen Browsern schon. details mit name und den Zeilen CSS aus diesem Beitrag funktioniert in React ohne Zustand und ohne Effekt, denn der Browser hält fest, welcher Eintrag offen ist. Wer den Zustand trotzdem in React braucht, etwa um ihn in der Adresse zu speichern, liest ihn über das toggle-Ereignis und setzt open nicht bei jedem Rendern neu, sonst laufen Browser und Komponente auseinander. Framer Motion misst die Höhe dagegen selbst und animiert damit auch in Firefox und Safari. Der Preis ist eine Abhängigkeit, ein eigener Button mit aria-expanded und der Verzicht auf die Suche in geschlossenen Einträgen, die details mitbringt.

Deine Frage war nicht dabei? Wir helfen gern weiter.

Kontakt aufnehmen