Data di pubblicazione: 6 novembre 2024
A partire da Chrome 131, hai più opzioni per definire lo stile della struttura degli elementi <details>
e <summary>
. Ora puoi utilizzare questi elementi durante la creazione di widget di divulgazione o a fisarmonica.
In particolare, le modifiche introdotte in Chrome 131 consentono l'utilizzo della proprietà display
su questi elementi e aggiungono uno pseudo-elemento ::details-content
per applicare lo stile alla parte che si espande e si comprime.
Impostazione display
sull'elemento <details>
In passato non era possibile modificare il tipo di visualizzazione dell'elemento <details>
. Questa limitazione è stata ora allentata, consentendoti, ad esempio, di utilizzare layout a griglia o flessibili nell'elemento <details>
.
Nell'esempio seguente, l'accordion esclusivo è costituito da diversi elementi <details>
posizionati uno accanto all'altro. Quando espandi uno degli elementi <details>
, i relativi contenuti vengono posizionati accanto a <summary>
.
Demo
Registrazione
Ciò si ottiene utilizzando un layout flessibile sull'elemento <details>
, utilizzando il seguente CSS:
details {
display: flex;
flex-direction: row;
}
Sono consentiti anche altri valori di visualizzazione, ad esempio grid
.
Una nota sull'utilizzo di display: inline
Un valore display
che può avere un risultato imprevisto è inline
. Non perché non funzioni, ma a causa delle limitazioni del parser HTML.
Quando inserisci un elemento <details>
all'interno di un paragrafo, l'analizzatore HTML è costretto a chiudere prima il paragrafo aperto, come definito nella sezione 13.2.6.4.7 dello standard HTML:
Un tag di apertura il cui nome è uno dei seguenti: "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"
Se la pila di elementi aperti ha un elemento p nell'ambito del pulsante, chiudi un elemento p. Inserisci un elemento HTML per il token.
Di conseguenza, il <details>
scorre nella direzione del blocco, indipendentemente dall'impostazione di display: inline
.
Ad esempio, il seguente markup
<p>Hello <details>…</details> world</p>
Diventa questo dopo l'analisi:
<p>Hello </p><details>…</details> world<p></p>
Puoi verificarlo di persona in questa demo ispezionando il markup analizzato utilizzando Chrome DevTools.
Tieni presente che questo vale solo per l'annidamento di <details>
all'interno di un <p>
. L'utilizzo di display: inline
su un <details>
all'interno di un <div>
funziona correttamente.
Lo pseudo-elemento ::details-content
Nei browser, l'elemento <details>
viene implementato utilizzando shadow DOM. Contiene un <slot>
per il riepilogo (con un elemento secondario di riepilogo predefinito) e un <slot>
per tutti i contenuti rimanenti, ovvero tutti gli elementi secondari dell'elemento <details>
, ad eccezione dell'elemento <summary>
.
<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>
Oltre a utilizzare più tipi di visualizzazione su <details>
, ora è possibile scegliere come target lo slot di contenuti utilizzando lo pseudo-elemento ::details-content
. Puoi utilizzare questa pseudo-classe per definire lo stile del contenitore che racchiude i contenuti dell'elemento <details>
.
details::details-content {
border: 5px dashed hotpink;
}
Per applicare lo stile impostato solo quando l'elemento <details>
è aperto, anteponi il selettore [open]
.
[open]::details-content {
border: 5px dashed hotpink;
}
Ti consigliamo di applicare lo stile allo pseudo-elemento ::details-content
solo quando l'elemento <details>
è nello stato [open]
.
Demo
Registrazione
Il tipo display
di ::details-content
è impostato su block
nel foglio di stile UA, mentre prima era display: contents
. In alcuni casi, questa modifica potrebbe essere a tuo svantaggio, ad esempio per i contenuti divulgati che si basano su height: 100%
. Se questo è un problema per te, puoi risolverlo impostando di nuovo il tipo display
su contents
, come segue: details[open]::details-content { display: contents; }
.
Animare lo pseudo-elemento ::details-content
Puoi animare i contenuti dell'elemento <details>
durante l'espansione. Nell'esempio seguente, la larghezza viene animata da 0px
a 300px
.
::details-content {
transition: width 0.5s ease, content-visibility 0.5s ease allow-discrete;
width: 0;
}
[open]::details-content {
width: 300px;
}
Oltre alla transizione di width
, deve essere eseguita anche la transizione della proprietà content-visibility
. Questo perché il suo valore cambia tra lo stato aperto e non aperto, come definito nel foglio di stile User-Agent. Poiché questa proprietà è animabile in modo discreto, devi utilizzare la parola chiave allow-discrete
per farla funzionare.
Se aggiungiamo questo risultato alla demo esclusiva dell'accordion condivisa in precedenza, otteniamo questo risultato:
Demo
Registrazione
Anche il height
può essere animato. Per animare fino a height: auto
, devi utilizzare interpolate-size
o calc-size()
. Inoltre, per evitare che i contenuti fuoriescano dallo pseudo ::details-content
, applica overflow: clip
.
::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 */
}
}
Puoi vedere il codice in azione nella seguente demo, ispirata all'accordion di Material UI. Il contenuto di ogni elemento <details>
viene animato in modo ottimale.
Demo
Registrazione
Nei browser che non supportano ::details-content
, il componente funziona comunque correttamente. L'unica cosa che i visitatori non vedono è l'animazione.
Rilevamento delle funzionalità
Per rilevare il supporto dello pseudo elemento ::details-content
in CSS, utilizza il seguente snippet.
@supports selector(::details-content) {
…
}
Puoi anche utilizzare questo rilevamento come controllo rivelatore per capire se il browser utilizzato dal visitatore supporta o meno i valori di visualizzazione aggiuntivi.
Considerazioni sull'accessibilità
L'introduzione dello pseudo-elemento ::details-content
e la possibilità di modificare il tipo di visualizzazione non influiscono sull'accessibilità dell'elemento <details>
.
Come in precedenza, almeno nei browser basati su Chromium e in conformità allo standard HTML, l'elemento <details>
è ricercabile e si espande automaticamente quando il browser tenta di scorrere fino ai suoi contenuti nascosti in risposta alla ricerca nella pagina, a ScrollToTextFragment e alla navigazione dei frammenti di elementi. Questo valore non cambia.
Tuttavia, prima di utilizzare gli accordion esclusivi, valuta se sono utili o dannosi per gli utenti. Sebbene l'utilizzo di un accordion esclusivo riduca lo spazio visivo occupato dai contenuti, gli utenti potrebbero dover aprire molti elementi per consumare tutte le informazioni. Ciò potrebbe frustrare gli utenti che vogliono esaminare più elementi contemporaneamente.
Come faccio a personalizzare il marcatore?
Attualmente lo stile del marcatore di elenco non è interoperabile perché esistono due approcci diversi: uno adottato da Gecko e (attuale) Chromium e un altro adottato da WebKit (che in precedenza era condiviso con Chromium).
Una volta che la funzionalità è interoperabile, il nostro obiettivo è darti un maggiore controllo su come applicare lo stile al marcatore.
Altre demo
Per concludere, ecco altre demo da guardare. Tutti utilizzano ::details-content
.
Accordion UIKit
Demo
Registrazione
Questa demo è basata su UIKit Accordion. Il codice è praticamente lo stesso dell'accordion Material UI condiviso in precedenza.
Widget di divulgazione parzialmente aperto
Demo
Registrazione
Questa demo mostra un widget di divulgazione parzialmente aperto il cui contenuto è già visibile sullo schermo. Per raggiungere questo obiettivo, content-visibility
è sempre impostato su visible
. Il height
viene animato utilizzando calc-size()
perché è coinvolto un calcolo.
::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 */
}
Per facilitare lo stile, i contenuti sono racchiusi in un div wrapper. Al div wrapper vengono applicati gli stili di layout, ad esempio padding
, e lo pseudo ::details-content
viene animato.