Crea un acordeón exclusivo con varios elementos <details>
que tengan el mismo name
.
El acordeón
Un patrón de IU común en la Web es un componente de acordeón. Este es un componente que consiste en varios widgets de divulgación que se pueden expandir (o contraer) de manera individual para mostrar (u ocultar) su contenido.
Para implementar este patrón en la Web, debes combinar algunos elementos <details>
y, por lo general, agruparlos visualmente para indicar que pertenecen juntos.
El exclusivo acordeón
Navegadores compatibles
Una variación del patrón de acordeón es el acordeón exclusivo, en el que solo se puede abrir uno de los widgets de divulgación al mismo tiempo.
Para lograrlo en la Web, ahora puedes agregar un atributo name
a los elementos <details>
. Cuando se usa este atributo, varios elementos <details>
que tienen el mismo valor name
forman un grupo semántico y se comportarán como un acordeón exclusivo. Cuando abras uno de los elementos <details>
del grupo, el que abriste antes se cerrará automáticamente.
<details name="learn-css">
<summary>Welcome to Learn CSS!</summary>
<p>…</p>
</details>
<details name="learn-css">
<summary>Box Model</summary>
<p>…</p>
</details>
<details name="learn-css">
<summary>Selectors</summary>
<p>…</p>
</details>
Una página puede tener varios acordeones exclusivos. Cada vez que usas un nuevo valor name
en un elemento <details>
, se crea un nuevo grupo lógico.
Ten en cuenta que los elementos <details>
que forman parte de un acordeón exclusivo no necesariamente tienen que ser del mismo nivel. Pueden estar dispersos por todo el documento. Es el atributo name
el que los agrupa, no su orden en el DOM.
Polyfill, el exclusivo acordeón
Con el siguiente JavaScript, es posible aplicar polyfill el comportamiento del acordeón exclusivo. El código se basa en el evento toggle
del elemento <details>
.
Cuando se abre un elemento <details>
con un name
, el código encuentra los otros elementos <details>
abiertos con el mismo valor para el atributo name
y los cierra.
document.querySelectorAll("details[name]").forEach(($details) => {
$details.addEventListener("toggle", (e) => {
const name = $details.getAttribute("name");
if (e.newState == "open") {
document
.querySelectorAll(`details[name=${name}][open]`)
.forEach(($openDetails) => {
if (!($openDetails === $details)) {
$openDetails.removeAttribute("open");
}
});
}
});
});
Algunas versiones anteriores de los navegadores no activan este evento toggle
. En esos navegadores, el código de polyfill no realizará ninguna acción. En términos de mejora progresiva, este es el comportamiento aceptable.