Meer stylingopties <details>

Gepubliceerd: 6 november 2024

Vanaf Chrome 131 heb je meer opties om de structuur van <details> en <summary> -elementen te stylen. Je kunt deze elementen nu gebruiken bij het bouwen van disclosure- of accordionwidgets.

De wijzigingen die in Chrome 131 zijn doorgevoerd, maken het met name mogelijk om de display -eigenschap op deze elementen te gebruiken. Ook wordt er een pseudo-element ::details-content toegevoegd om het gedeelte dat kan worden uitgevouwen en samengevouwen, op te maken.

Browser Support

  • Chroom: 131.
  • Rand: 131.
  • Firefox: 143.
  • Safari: 18.4.

Source

display instellen op het <details> -element

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

In het volgende voorbeeld bestaat de exclusieve accordeon uit meerdere <details> -elementen die naast elkaar zijn geplaatst. Wanneer u een van de <details> -elementen uitvouwt, wordt de inhoud ervan naast de <summary> geplaatst.

Demonstratie

Opname

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

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

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

Ook andere weergavewaarden, zoals grid , zijn toegestaan.

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 beperkingen van de HTML-parser.

Wanneer u een <details> -element in een alinea plaatst, wordt de HTML-parser gedwongen eerst de open 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", "dialoog", "dir", "div", "dl", "fieldset", "figcaption", "figure", "footer", "header", "hgroup", "main", "menu", "nav", "ol", "p", "search", "section", "summary", "ul"

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

Hierdoor stroomt de <details> in de blokrichting, ongeacht of u display: inline hebt ingesteld.

Bijvoorbeeld de volgende markering

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

Wordt dit na het parsen:

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

Merk op dat dit alleen van toepassing is op het nesten <details> in een <p> . Het gebruik van 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 samenvattingselement) en een <slot> voor alle resterende content, wat betekent dat alle onderliggende elementen van het <details> -element behalve het <summary> -element aanwezig zijn.

<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 content slot nu ook worden getarget met het pseudo-element ::details-content . U kunt dit pseudo-element gebruiken om de container te stylen die de content van het <details> -element omhult.

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

Als u de set-stijl alleen wilt toepassen als het <details> -element open is, voegt u de selector [open] eraan toe.

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

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

Demonstratie

Opname

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

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

Animeren van de ::details-content pseudo

U kunt de inhoud van het <details> -element animeren terwijl het groter wordt. 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 de overgang van de width naar de inhoud, moet ook de eigenschap content-visibility een overgang ondergaan. Dit komt doordat de waarde ervan verandert tussen de ongeopende en geopende status, zoals gedefinieerd in de User-Agent-stijlpagina. Omdat deze eigenschap een discreet animeerbare eigenschap is, hebt u het trefwoord allow-discrete nodig om deze te laten werken.

Als je dit toevoegt aan de exclusieve accordeondemo die eerder is gedeeld, is het resultaat als volgt:

Demonstratie

Opname

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

De height kan ook worden geanimeerd. Om te animeren naar height: auto moet je interpolate-size of calc-size() gebruiken . Om te voorkomen dat de inhoud uit de pseudo ::details-content lekt, kun je overflow: clip toepassen.

::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 wordt mooi geanimeerd.

Demonstratie

Opname

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

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

Functiedetectie

Om de ondersteuning voor het pseudo ::details-content in CSS te detecteren, gebruikt u het volgende fragment.

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

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

Toegankelijkheidsoverwegingen

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

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

Overweeg echter, voordat u exclusieve accordeons gebruikt, of dit nuttig of schadelijk is voor gebruikers. Hoewel het gebruik van een exclusieve accordeon de hoeveelheid visuele ruimte die content inneemt vermindert, moeten gebruikers mogelijk meerdere items openen om alle informatie te verwerken. Dit kan frustrerend zijn voor gebruikers die meerdere items tegelijk willen bekijken.

Hoe zit het met de styling van de marker?

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

Zodra de functie interoperabel is, willen we u meer controle geven over de stijl van de marker.

Meer demo's

Tot slot zijn hier nog een paar demo's om te bekijken. Ze gebruiken allemaal ::details-content .

UIKit Accordeon

Demonstratie

Opname

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

Deze demo is gebaseerd op de UIKit Accordion . De code is vrijwel gelijk aan die van de Material UI Accordion die eerder werd gedeeld.

Gedeeltelijk geopende openbaarmakingswidget

Demonstratie

Opname

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

Deze demo toont een gedeeltelijk geopende onthullingswidget 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 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 een gemakkelijke styling wordt de content in een wrapper-div geplaatst. De wrapper-div krijgt de lay-outstijlen, zoals padding , en de pseudo ::details-content wordt geanimeerd.