soy Kseso y esto EsCSS

Elementos Details y Summary: función toggle nativa de Html5

Los nuevos elementos de HTML5 DETAILS y SUMMARY a fondo. Sus particularidades de funcionamiento y los secretos para aplicarles estilos CSS.

Elementos Details y Summary: función toggle nativa de Html5

·Por Kseso ✎ 6
Elementos Details y Summary: función toggle nativa de Html5

HTML5 vino, bueno, está en camino, con multitud de elementos que facilitan la interacción del usuario con los contenidos de la página. Y además lo hace de forma nativa y sencilla: el desarrollador sólo tiene que añadir esos elementos y es el navegador quien implementa los recursos necesarios para su correcto funcionamiento.

Uno de estos nuevos elementos interactivos es details y su hijo summary

Básicamente lo que hace es lo mismo que la función toggle: el elemento details de entrada oculta todo su contenido excepto lo incluido en summary y sólo cuando el usuario clica sobre éste último los muestra.

Podríamos decir que su comportamiento es el del típico elemento que por defecto se muestra colapsado y sólo a demanda del visitante se expande para mostrar su contenido. Como el ejemplo siguiente:

Marcado html de Details y Summary

Click para expandir o colapsar Este texto se muestra o se esconde al pinchar en la leyenda anterior.

Su marcado inicialmente es sencillo:

<details> <summary>Click para expandir o colapsar</summary> Este texto se muestra o se esconde al pinchar en la leyenda anterior. </details>

Soporte de navegadores a Details y Summary

Puedes consultar la página caniuse.com para estar al tanto de los navegadores y sus versiones que ya implementan en su núcleo soporte nativo a a los elementos details y summary

Hoy [09/2017] sólo los los IE´s/Edge y Opera Mini no lo hacen.
Firefox, Chrome, Safari y Opera sí, al igual que el navegador de Android.

Details en Details

El ejemplo anterior del marcado html de details es el mínimo funcional. Pero nada impide añadir elementos dentro de details:

<details> <summary>Listado</summary> <dl> <dt>Uno</dt> <dd>Definición de Uno</dd> <dt>Dos</dt> <dd>Definición de Dos</dd> </dl> </details>

¿Te suena? Cambia la lista de definición (dl) por una lista desordenada (ul) y tienes el típico menú desplegable de un sólo nivel en el que nos ahorramos todo lo necesario para mostrar y ocultar las opciones.

Pero este marcado se puede llevar un paso más allá porque el elemento details admite como hijos otros elementos details. Sólo se precisa que cada uno cuente con su correspondiente summary para hacerlo funcional:

See the Pen BjWVvJ by Kseso (@Kseso) on CodePen.

El elemento summary también admite otros elementos dentro de él.

<details> <summary> <label for='nombre'>Texto</label> </summary> <!-- otro contenido --> </details>

Estilos CSS al elemento details y summary

Habrás visto que no he añadido ningún estilo CSS a los ejemplos mostrados hasta ahora. Todo lo relativo a su funcionamiento lo pone el navegador. Eso y unos estilos por defecto como a cualquier otro elemento.

Para darle la apariencia sólo tienes que usar su nombre como selector CSS:

details { /*estilos muy chu-chu-chulos*/ } summary { /*estilos muy chu-chu-chulos*/ }

Estilos CSS para details desplegado

Es posible aplicar reglas específicas para cuando el elemento details se muestra desplegado tras pinchar en su summary correspondiente.

Para ello nis servimos de una particularidad que ocurre al clicar el summary (como con otros elementos como los radio).

Al pinchar en el elemento summary hijo de cada details padre el navegador añade a éste último (el details padre) el atributo open sin valor (no añade ni el signo igual = ni cadena textual tras él entre comillas).

elemento details con atributo open tras pinchar su summary
Elemento details con atributo open tras pinchar su summary

Y aquí viene de perlas un viejo conocido: el selector CSS por nombre de atributo HTML:

details[open] { /* estilos muy chu-chu-chulos para el elemento details en su estado desplegado */ } details[open] > summary { /*estilos muy chu-chu-chulos para el elemento summary en su details padre desplegado */ }

Y como es lógico, el selector CSS details[open] lo podemos usar para afectar a cualquier elemento contenido en él cuando se despliega y muestra.

Actualización Febrero 2016
Hay un hilo en discusión en la lista de Correos del W3c al respecto: la propuesta es que a details y/o summary le sean de aplicación las particularidades de los ítems de lista (display: list-item) y por lo tanto también sea efectivo el pseudoelemento ::marker en ellos.

En teoría el navegador añade al elemento summary un pequeño triángulo. ▸ para details cerrado y ▾ desplegado.

En los navegadores webkit podemos acceder a esta marca identificativa con el pseudoelemento privativo ::-webkit-details-marker

summary::-webkit-details-marker { /* estilos muy chu-chu-chulos como color y font-size*/ } /*o diferenciarlo al desplegarse el contenido*/ details[open] > summary::-webkit-details-marker { }

O ir un paso más allá si no te gustan los triángulos y quieres mostrar tu propia marca:

summary::-webkit-details-marker { display: none } summary:before { content: "+"; } details[open] > summary:before { content: "~"; }

Ver Demo en Codepen

Todo Junto en una demo

Y como colofón un viejo conocido realizado de forma más sencilla con details y summary: Navegación interna en la misma página desde un sumario o tabla de contenidos con enlace a cada capítulo o apartado:

See the Pen Details & summary for native toggle by Kseso (@Kseso) on CodePen.

Esta demo no está optimizada para pantallas pequeñas (estrechas). Bastaría añadirle alguna media query con sus reglas correspondientes. Pero no es ese el objeto del artículo.

Alterando el despliegue

Vía Twitter me plantea @AntBogarin una cuestión interesante que había pasado por alto: por defecto el contenido replegado se despliega hacia abajo:

No debería plantear mayor problema cambiar este comportamiento, siempre teniendo en cuenta ciertas particularidades y los detalles propios de cada realización. Al igual que se hace con los menús desplegables de múltiples niveles, pero teniendo en cuenta que el despliegue de un details no fuerza el cierre de otros, por lo que hay que prever y evitar los solapamientos.

Una realización rápida y a modo de ejemplo:

See the Pen zrZJzp by Kseso (@Kseso) on CodePen.

Y otro típico menú desplegable con details y summary:

See the Pen adJRzP by Kseso (@Kseso) on CodePen.

Enlaces de interés: lecturas y ayudas

  1. Details y Summary en la especificación W3c
  2. Cross-Browser Polyfills

avatar del Editor del blog

Ramajero Argonauta, Enredique Amanuense de CSS.
#impoCSSible inside
Dicen que, en español, EsCss es el mejor blog de CSS. Posíblemente exageren.
@Kseso EsCss Don Kseso Kseso