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