Contenido desplegable con details y summary
Envuelve el contenido en <details> y pon primero un <summary>. El summary sigue visible; todo lo demás queda oculto hasta que el lector lo pulsa:
Pulsa la pregunta para abrirla, y otra vez para cerrarla. El navegador añade el triángulo, hace que el summary reciba el foco, lo alterna con Enter o Espacio y les dice a los lectores de pantalla si está expandido o contraído. No interviene JavaScript.
Si omites <summary>, el navegador muestra en su lugar una etiqueta por defecto ("Detalles" en español).
Abierto por defecto
El atributo booleano open muestra el contenido desde el principio. El navegador añade y quita open a medida que el lector lo alterna, así que también sirve de punto de apoyo para el estilo:
La caja abierta tiene un borde azul gracias a details[open]. Abre "Returns" y también se vuelve azul; los dos pueden estar abiertos a la vez.
Acordeón: solo uno abierto a la vez
Dale a varios elementos <details> el mismo name y se convierten en un grupo exclusivo: al abrir uno se cierran los demás. Esto antes necesitaba JavaScript y ahora funciona solo con el atributo en las versiones actuales de Chrome, Edge, Firefox y Safari:
Abre la segunda pregunta y la primera se cierra. Quita los atributos name y vuelven a abrirse de forma independiente. Un acordeón exclusivo oculta contenido que el lector podría querer comparar, así que úsalo cuando las secciones sean alternativas, y <details> normales cuando la gente pueda querer varias abiertas.
Dar estilo al marcador
El triángulo es un marcador de lista en el summary. list-style: none lo quita (la regla ::-webkit-details-marker cubre Safari), y un pseudoelemento puede dibujar tu propio indicador:
El signo más gira 45 grados y se convierte en una cruz cuando se abre la sección. Mantén un estilo de foco visible como el contorno :focus-visible de aquí: una vez que quitas el marcador por defecto, el anillo de foco es en lo que se apoyan quienes usan el teclado.
El evento toggle y la propiedad open
JavaScript puede leer y asignar details.open, y el evento toggle se dispara después de cada cambio, lo haya provocado un clic, una tecla o un script:
"Expand all" pone open en los dos, y el registro muestra el último evento toggle. El evento no se propaga, así que escúchalo en cada elemento <details> en lugar de en un padre.
Qué va en un summary
Un summary contiene texto, elementos en línea o un encabezado cuando el título de la sección pertenece al esquema de la página:
<details>
<summary><h3>Refund policy</h3></summary>
<p>...</p>
</details>
Evita enlaces, botones y campos de formulario dentro de <summary>: el summary ya es un control, así que un control dentro de él es fácil de pasar por alto o de pulsar por error, y los lectores de pantalla anuncian mal los controles anidados. Pon el contenido interactivo en el cuerpo del <details>.
Errores comunes
- Construir un desplegable con un
<div>y JavaScript.<details>ya gestiona los clics, las teclas y el estado para los lectores de pantalla. Cuando de verdad necesites un desplegable propio, usa un botón conaria-expanded. - Poner
<summary>en cualquier sitio que no sea el primero. Tiene que ser el primer hijo de<details>. - Ocultar el marcador sin sustituto. Da a los lectores alguna señal de que el summary se abre, como el signo más de arriba.
- Usar
displaypara ocultar el contenido. Alternaopen; un CSS que fuerza el contenido a verse u ocultarse choca con el estado del navegador. - Grupos exclusivos para contenido que la gente compara. Usa
namesolo cuando tenga sentido una sola sección abierta a la vez.
Preguntas frecuentes
¿Qué hacen details y summary en HTML?
<details> crea un widget desplegable: una sección que se puede abrir y cerrar. Su primer hijo, <summary>, es la etiqueta siempre visible; al pulsarla (o al pulsar Enter o Espacio cuando tiene el foco) se muestra u oculta todo lo demás que hay dentro de <details>.
¿Cómo hago que un elemento details esté abierto por defecto?
Añade el atributo booleano open: <details open>. El navegador añade y quita ese atributo cuando el usuario lo abre o lo cierra, así que el CSS puede dar estilo a details[open].
¿Cómo hago un acordeón en el que solo haya una sección abierta?
Dale a todos los <details> del grupo el mismo atributo name, por ejemplo name="faq". Al abrir uno se cierran los demás de ese grupo, sin JavaScript.
¿Cómo quito o cambio la flecha de un details summary?
Pon list-style: none en summary y añade summary::-webkit-details-marker { display: none; } para Safari. Después dibuja tu propio indicador, por ejemplo con summary::after, y cámbialo con details[open] summary::after.
¿Puedo detectar cuándo se abre un elemento details?
Sí. Escucha el evento toggle en el elemento <details> y lee su propiedad open. Asignar details.open = true en JavaScript lo abre.