Meer stylingopties <details>

Gepubliceerd: 6 november 2024

Vanaf Chrome 131 heb je meer opties om de structuur van <details> en <summary> -elementen op te maken. U kunt deze elementen nu gebruiken bij het bouwen van openbaarmakings- of accordeonwidgets.

Met name de wijzigingen die in Chrome 131 zijn geïntroduceerd, maken het gebruik van de display eigenschap voor deze elementen mogelijk en voegen een ::details-content pseudo-element toe om het deel dat uit- en samenvouwt vorm te geven.

Browserondersteuning

  • Chroom: 131.
  • Rand: niet ondersteund.
  • Firefox: niet ondersteund.
  • Safari: niet ondersteund.

display op het <details> element

Historisch gezien was het niet mogelijk om het weergavetype van het <details> -element te wijzigen. Deze beperking is nu versoepeld, waardoor u bijvoorbeeld raster- of flex-indelingen kunt gebruiken op het <details> -element.

In het volgende voorbeeld bestaat de exclusieve accordeon uit meerdere naast elkaar geplaatste <details> elementen. Bij het uitvouwen van een van de <details> -elementen wordt de inhoud ervan naast de <summary> geplaatst.

Demo

Opname

Opname van https://codepen.io/web-dot-dev/pen/VwoBQjY in Chrome 131

Dit wordt bereikt door een flexibele lay-out op het <details> -element te gebruiken, met behulp van de volgende CSS:

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

Ook toegestaan ​​zijn andere weergavewaarden zoals grid .

Een opmerking over het gebruik van display: inline

Een display die een onverwachte uitkomst kan hebben, is inline . Niet omdat het niet werkt, maar vanwege de beperkingen van de HTML-parser.

Wanneer een <details> -element in een alinea wordt geplaatst, wordt de HTML-parser gedwongen eerst de geopende alinea te sluiten, zoals gedefinieerd in sectie 13.2.6.4.7 van de HTML-standaard :

Een starttag waarvan de tagnaam een ​​van de volgende is: "adres", "artikel", "aside", "blockquote", "center", "details", "dialog", "dir", "div", "dl", "fieldset", "figcaption", "figure", "footer", "header", "hgroup", "main", "menu", "nav", "ol", "p", "search", "section ", "samenvatting", "ul"

Als de stapel open elementen een ap-element binnen het bereik van de knop heeft, sluit dan het ap-element. Voeg een HTML-element in voor het token.

Als gevolg hiervan stroomt de <details> in de blokrichting, ongeacht of u display: inline heeft ingesteld.

Bijvoorbeeld de volgende opmaak

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

Wordt dit na parseren:

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

U kunt het zelf zien in deze demo door de geparseerde markup te inspecteren met Chrome DevTools.

Houd er rekening mee dat dit alleen van toepassing is op het nesten van <details> in een <p> . display: inline op een <details> in een <div> werkt prima.

De ::details-content pseudo

In browsers wordt het <details> -element geïmplementeerd met behulp van Shadow DOM . Het bevat één <slot> voor de samenvatting (met een standaard samenvattingskind) en een <slot> voor alle overige inhoud, dat wil zeggen alle onderliggende inhoud van het <details> -element behalve het <summary> -element.

<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>

Naast het gebruik van meer weergavetypen op <details> , kan de inhoudssleuf nu worden getarget met behulp van het ::details-content pseudo-element. U kunt deze pseudo gebruiken om de container op te maken die de inhoud van het <details> -element omhult.

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

Om de ingestelde stijl alleen toe te passen wanneer het <details> -element zich in de open status bevindt, plaatst u de [open] -selector ervoor.

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

Het wordt aanbevolen om alleen styling toe te passen op de ::details-content pseudo wanneer het <details> element zich in de [open] status bevindt.

Demo

Opname

Opname van https://codepen.io/web-dot-dev/pen/oNKMEYv in Chrome 131

Het display van ::details-content is ingesteld op block in het UA-stijlblad, terwijl dit voorheen display: contents was. Deze wijziging kan in sommige gevallen tegen u werken, zoals bij openbaar gemaakte inhoud die afhankelijk is van height: 100% . Als dit een probleem voor u is, kunt u dit omzeilen door het display weer in te stellen op contents , bijvoorbeeld: details[open]::details-content { display: contents; } .

Animeren van de ::details-content pseudo

U kunt de inhoud van het <details> -element animeren terwijl het wordt uitgevouwen. In het volgende voorbeeld wordt de breedte geanimeerd van 0px tot 300px .

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

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

Naast het overzetten van de width moet ook de eigenschap content-visibility overgaan. Dit komt omdat de waarde ervan verandert tussen de ongeopende en geopende status, zoals gedefinieerd in het User-Agent-stijlblad. Omdat die eigenschap een eigenschap is die discreet kan worden geanimeerd, hebt u het sleutelwoord allow-discrete nodig om deze te laten werken.

Toegevoegd aan de exclusieve accordeondemo die eerder werd gedeeld, wordt het resultaat dit:

Demo

Opname

Opname van https://codepen.io/web-dot-dev/pen/XWvBZNo in Chrome 131

De height kan ook worden geanimeerd. Om naar height: auto te animeren, moet u interpolate-size of calc-size() gebruiken . Om te voorkomen dat de inhoud uit de ::details-content pseudo komt, past u bovendien overflow: clip erop toe.

::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 */
    }
}

Je kunt de code in actie zien in de volgende demo, geïnspireerd door de accordeon van Material UI . De inhoud van elk <details> -element is mooi geanimeerd.

Demo

Opname

Opname van https://codepen.io/web-dot-dev/pen/ExqpQZM in Chrome 131

In browsers zonder ondersteuning voor ::details-content werkt de component nog steeds prima. Het enige dat bezoekers niet te zien krijgen, is de animatie.

Functiedetectie

Gebruik het volgende fragment om detectieondersteuning voor de ::details-content pseudo in CSS te bieden.

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

U kunt deze detectie ook gebruiken als een veelbetekenende controle om erachter te komen of de browser die uw bezoeker gebruikt de extra weergavewaarden ondersteunt of niet.

Toegankelijkheidsoverwegingen

De introductie van het ::details-content pseudo-element en de mogelijkheid om het weergavetype te wijzigen heeft geen invloed op de toegankelijkheid van het <details> element.

Net als voorheen, tenminste in Chromium-gebaseerde browsers en volgens HTML Standard , is het <details> -element doorzoekbaar en wordt het automatisch uitgevouwen wanneer de browser naar de verborgen inhoud probeert te scrollen als reactie op find-in-page, ScrollToTextFragment en elementfragmentnavigatie . Dit verandert niet.

Voordat u exclusieve accordeons gebruikt, moet u echter overwegen of dit nuttig of schadelijk is voor gebruikers. Hoewel het gebruik van een exclusieve accordeon de hoeveelheid visuele ruimte die de inhoud in beslag neemt, vermindert, moeten gebruikers mogelijk veel items openen om alle informatie te kunnen consumeren. Dit kan gebruikers frustreren die meerdere items tegelijk willen bekijken.

Hoe zit het met het stylen van de marker?

Momenteel is de stijl van de lijstmarkering niet interoperabel omdat er twee verschillende benaderingen zijn: één van Gecko en (huidige) Chromium, en een andere van WebKit (die eerder werd gedeeld met Chromium).

Zodra de functie interoperabel is, is het ons doel om u betere controle te geven over de stijl van de markering.

Meer demo's

Ter afsluiting zijn hier nog enkele demo's die u kunt bekijken. Ze gebruiken allemaal ::details-content .

UIKit-accordeon

Demo

Opname

Opname van https://codepen.io/web-dot-dev/pen/rNXrJyQ in Chrome 131

Deze demo is gebouwd naar de UIKit-accordeon . De code is vrijwel hetzelfde als de Material UI-accordeon die eerder werd gedeeld.

Gedeeltelijk geopende openbaarmakingswidget

Demo

Opname

Opname van https://codepen.io/web-dot-dev/pen/PoMBQmW in Chrome 131

Deze demo bevat een gedeeltelijk geopende openbaarmakingswidget waarvan de inhoud al zichtbaar is op het scherm. Om dit te bereiken wordt de content-visibility altijd ingesteld op visible . De height wordt geanimeerd met behulp van calc-size() omdat er een berekening bij betrokken is.

::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 */
}

Voor het gemak van het stylen is de inhoud verpakt in een wrapper-div. De wrapper div krijgt de lay-outstijlen zoals padding toegepast en de ::details-content pseudo wordt geanimeerd.