Weitere Optionen für den Stil <details>

Veröffentlicht: 6. November 2024

Ab Chrome 131 haben Sie mehr Möglichkeiten, die Struktur von <details>- und <summary>-Elementen zu gestalten. Sie können diese Elemente jetzt beim Erstellen von Offenlegungs- oder Akkordeon-Widgets verwenden.

Insbesondere ermöglichen die Änderungen in Chrome 131 die Verwendung der Eigenschaft display für diese Elemente und fügen ein Pseudo-Element ::details-content hinzu, um den Teil zu stylen, der maximiert und minimiert werden kann.

Unterstützte Browser

  • Chrome: 131.
  • Edge: 131.
  • Firefox: Nicht unterstützt.
  • Safari: Nicht unterstützt.

display für das Element <details> festlegen

Bisher war es nicht möglich, den Darstellungstyp des <details>-Elements zu ändern. Diese Einschränkung wurde jetzt aufgehoben. Sie können jetzt beispielsweise Grid- oder Flex-Layouts für das <details>-Element verwenden.

Im folgenden Beispiel besteht das exklusive Akkordeon aus mehreren nebeneinander angeordneten <details>-Elementen. Wenn Sie eines der <details>-Elemente maximieren, wird der Inhalt neben dem <summary> platziert.

Demo

Aufzeichnung

Aufzeichnung von https://codepen.io/web-dot-dev/pen/VwoBQjY in Chrome 131

Dazu wird für das <details>-Element ein Flex-Layout mit dem folgenden CSS verwendet:

details {
  display: flex;
  flex-direction: row;
}

Auch andere Anzeigewerte wie grid sind zulässig.

Hinweis zur Verwendung von display: inline

Ein display-Wert, der zu unerwarteten Ergebnissen führen kann, ist inline. Nicht, weil es nicht funktioniert, sondern aufgrund von Einschränkungen des HTML-Parsers.

Wenn Sie ein <details>-Element in einen Absatz einfügen, zwingt das den HTML-Parser, zuerst den offenen Absatz zu schließen, wie in Abschnitt 13.2.6.4.7 des HTML-Standards definiert:

Ein Start-Tag mit einem der folgenden Tag-Namen: „address“, „article“, „aside“, „blockquote“, „center“, „details“, „dialog“, „dir“, „div“, „dl“, „fieldset“, „figcaption“, „figure“, „footer“, „header“, „hgroup“, „main“, „menu“, „nav“, „ol“, „p“, „search“, „section“, „summary“, „ul“

Wenn der Stapel der geöffneten Elemente ein p-Element im Bereich der Schaltfläche hat, schließen Sie ein p-Element. Fügen Sie ein HTML-Element für das Token ein.

Daher fließt <details> in die Blockrichtung, unabhängig davon, ob Sie display: inline festgelegt haben.

Beispiel:

<p>Hello <details>…</details> world</p>

Nach dem Parsen sieht das so aus:

<p>Hello </p><details>…</details> world<p></p>

In dieser Demo können Sie sich das selbst ansehen, indem Sie das geparste Markup mit den Chrome DevTools prüfen.

Hinweis: Dies gilt nur für das Verschachteln von <details> in <p>. Die Verwendung von display: inline auf einem <details> in einem <div> funktioniert einwandfrei.

Die Pseudospalte ::details-content

In Browsern wird das <details>-Element mithilfe von Shadow DOM implementiert. Es enthält eine <slot> für die Zusammenfassung (mit einem standardmäßigen untergeordneten Element für die Zusammenfassung) und eine <slot> für alle übrigen Inhalte, also alle untergeordneten Elemente des <details>-Elements mit Ausnahme des <summary>-Elements.

<details>
  ↳ #shadow-root (user-agent)
      <slot id="details-summary">
        <summary>Details</summary>
        <!-- The summary goes here -->
      </slot>
      <slot id="details-content">
        <!-- All content goes here -->
      </slot>
</details>

Neben der Verwendung weiterer Anzeigentypen für <details> kann der Inhalts-Slot jetzt auch über das Pseudo-Element ::details-content ausgerichtet werden. Mit diesem Pseudo können Sie den Container stylen, der den Inhalt des <details>-Elements umschließt.

details::details-content {
  border: 5px dashed hotpink;
}

Wenn der festgelegte Stil nur angewendet werden soll, wenn sich das <details>-Element im geöffneten Zustand befindet, fügen Sie ihm den Selektor [open] voran.

[open]::details-content {
  border: 5px dashed hotpink;
}

Es wird empfohlen, das Styling nur auf das ::details-content-Pseudoelement anzuwenden, wenn sich das <details>-Element im Status [open] befindet.

Demo

Aufzeichnung

Aufzeichnung von https://codepen.io/web-dot-dev/pen/oNKMEYv in Chrome 131

Der display-Typ von ::details-content ist im UA-Stylesheet auf block festgelegt, zuvor war es display: contents. Diese Änderung kann sich in einigen Fällen nachteilig auf Sie auswirken, z. B. bei offengelegten Inhalten, die auf height: 100% basieren. Wenn das ein Problem für Sie darstellt, können Sie den display-Typ auf contents zurücksetzen, z. B. so: details[open]::details-content { display: contents; }.

::details-content-Pseudoelement animieren

Sie können den Inhalt des <details>-Elements beim Maximieren animieren. Im folgenden Beispiel wird die Breite von 0px auf 300px animiert.

::details-content {
  transition: width 0.5s ease, content-visibility 0.5s ease allow-discrete;
  width: 0;
}

[open]::details-content {
  width: 300px;
}

Neben der Umstellung von width muss auch die Property content-visibility umgestellt werden. Das liegt daran, dass sich der Wert zwischen dem ungeöffneten und dem geöffneten Zustand ändert, wie im User-Agent-Stylesheet definiert. Da diese Property nur diskret animiert werden kann, ist das Schlüsselwort allow-discrete erforderlich.

In Kombination mit der zuvor geteilten Akkordeon-Demo sieht das so aus:

Demo

Aufzeichnung

Aufzeichnung von https://codepen.io/web-dot-dev/pen/XWvBZNo in Chrome 131

Die height kann auch animiert werden. Wenn Sie eine Animation zu height: auto erstellen möchten, müssen Sie interpolate-size oder calc-size() verwenden. Um zu verhindern, dass der Inhalt über den ::details-content-Pseudocode hinausragt, wenden Sie außerdem overflow: clip darauf an.

::details-content {
    transition: height 0.5s ease, content-visibility 0.5s ease allow-discrete;
    height: 0;
    overflow: clip;
}

/* Browser supports interpolate-size */
@supports (interpolate-size: allow-keywords) {
    :root {
        interpolate-size: allow-keywords;
    }

    [open]::details-content {
        height: auto;
    }
}

/* Fallback for browsers with no interpolate-size support */
@supports not (interpolate-size: allow-keywords) {
    [open]::details-content {
        height: 150px;
        overflow-y: scroll; /* In case the contents should be taller than 150px */
    }
}

In der folgenden Demo, die vom Akkordeon-Widget von Material UI inspiriert ist, können Sie den Code in Aktion sehen. Der Inhalt jedes <details>-Elements wird schön animiert.

Demo

Aufzeichnung

Aufzeichnung von https://codepen.io/web-dot-dev/pen/ExqpQZM in Chrome 131

In Browsern ohne Unterstützung für ::details-content funktioniert die Komponente weiterhin einwandfrei. Die Besucher sehen nur die Animation nicht.

Funktionserkennung

Verwenden Sie das folgende Snippet, um die Unterstützung für das ::details-content-Pseudoelement in CSS zu prüfen.

@supports selector(::details-content) {
  
}

Sie können diese Erkennung auch als zuverlässige Prüfung verwenden, um herauszufinden, ob der Browser Ihres Besuchers die zusätzlichen Anzeigenwerte unterstützt oder nicht.

Barrierefreiheit

Die Einführung des ::details-content-Pseudoelements und die Möglichkeit, den Darstellungstyp zu ändern, haben keine Auswirkungen auf die Barrierefreiheit des <details>-Elements.

Wie bisher ist das Element <details> mindestens in Chromium-basierten Browsern und gemäß dem HTML-Standard suchbar und wird automatisch maximiert, wenn der Browser versucht, auf den ausgeblendeten Inhalt zu scrollen, als Reaktion auf die Navigation „Auf Seite suchen“, „Zu Textfragment scrollen“ und „Elementfragment“. Das ändert sich nicht.

Bevor Sie jedoch ein Akkordeon verwenden, sollten Sie überlegen, ob es für Nutzer hilfreich oder schädlich ist. Mit einem exklusiven Akkordeon wird zwar der visuelle Platz reduziert, den die Inhalte einnehmen, aber Nutzer müssen möglicherweise viele Elemente öffnen, um alle Informationen zu sehen. Das kann für Nutzer frustrierend sein, die sich mehrere Artikel gleichzeitig ansehen möchten.

Wie sieht es mit dem Stil der Markierung aus?

Derzeit ist das Styling der Listenmarkierung nicht interoperabel, da es zwei unterschiedliche Ansätze gibt: einen von Gecko und (aktuell) Chromium und einen von WebKit (der zuvor mit Chromium geteilt wurde).

Sobald die Funktion interoperabel ist, möchten wir Ihnen mehr Möglichkeiten zur Gestaltung der Markierung bieten.

Weitere Demos

Zum Abschluss noch ein paar weitere Demos: Sie verwenden alle ::details-content.

UIKit-Akkordeon

Demo

Aufzeichnung

Aufzeichnung von https://codepen.io/web-dot-dev/pen/rNXrJyQ in Chrome 131

Diese Demo basiert auf dem UIKit-Accordion. Der Code ist praktisch identisch mit dem Akkordeon der Material UI, das wir bereits kennen.

Teilweise geöffnetes Offenlegungs-Widget

Demo

Aufzeichnung

Aufzeichnung von https://codepen.io/web-dot-dev/pen/PoMBQmW in Chrome 131

In dieser Demo ist ein teilweise geöffnetes Offenlegungs-Widget zu sehen, dessen Inhalt bereits auf dem Bildschirm zu sehen ist. Dazu ist content-visibility immer auf visible festgelegt. Die height wird mit calc-size() animiert, da eine Berechnung erforderlich ist.

::details-content {
  content-visibility: visible; /* Make it always visible */
    
  transition: height 0.5s ease;
  height: 150px;
  overflow: clip;
}

[open]::details-content {
  height: calc-size(auto, size + 0.5rem); /* calc-size because we need to add a length */
}

Für die einfache Formatierung werden die Inhalte in ein Wrapper-Div eingefügt. Auf das Wrapper-Div werden Layoutstile wie padding angewendet und das Pseudo-Element ::details-content wird animiert.