Cómo animar un acordeón sin tirones
Por qué animar la altura es caro, las dos técnicas fiables, cómo tratar el contenido interior y las reglas de accesibilidad que un acordeón debe mantener.
Idea clave
Animar la altura obliga al navegador a recalcular el diseño en cada fotograma, y por eso los acordeones tiemblan. La solución fiable es animar una transformación o un contenedor recortado en lugar de la altura, o medir el contenido y animar hasta un valor en píxeles conocido. Mantén el contenido legible mientras se mueve y no dejes que la animación rompa aria-expanded ni el acceso por teclado.
Por qué animar la altura es caro
La altura es una propiedad de diseño. Cuando cambia, el navegador recalcula la posición de todo lo que hay debajo, en cada fotograma. En un panel pequeño suele ir bien; dentro de una página larga o de una lista de acordeones, no. Las transformaciones y la opacidad puede gestionarlas el compositor.
Dos técnicas que funcionan
La primera mide la altura del contenido en JavaScript y anima de cero a ese valor en píxeles, para luego devolver la altura a auto. La segunda mantiene el contenedor fijo y anima una fila de cuadrícula de 0fr a 1fr, o recorta una transformación. Los navegadores empiezan a admitir tamaños intrínsecos animables, pero el soporte no es universal.
Trata el contenido, no solo la caja
El texto que se desliza mientras se desvanece puede verse borroso. Un desvanecido corto, o un escalonado pequeño para las filas interiores, se lee mejor que mover párrafos en vertical. No animes todos los hijos: elige los uno o dos que marcan la jerarquía.
Abre despacio, cierra rápido
Abrir revela información, así que el usuario necesita un momento para seguirla; cerrar es un descarte y puede ser más rápido. Si se pueden abrir varias secciones a la vez, acorta el cierre para que la página se asiente antes.
Reglas de accesibilidad que la animación no puede romper
La cabecera debe ser un botón con aria-expanded y el panel debe estar vinculado con aria-controls. El contenido oculto no debe ser alcanzable por teclado ni por lectores de pantalla. Si animas con un contenedor extra, comprueba que no atrapa el foco ni deja anunciar contenido plegado.
Movimiento reducido y listas largas
Con movimiento reducido, salta el movimiento de altura y muestra el panel de inmediato, o usa un desvanecido muy corto. En listas largas, anima solo el panel que cambió y deja que el resto de la página se asiente sin movimiento.
Fragmento de implementación en producción
/* Grid-row technique: no JavaScript measurement */
.panel {
display: grid;
grid-template-rows: 0fr;
transition: grid-template-rows 220ms ease;
}
.panel[data-open="true"] {
grid-template-rows: 1fr;
}
.panel > div {
overflow: hidden;
}
@media (prefers-reduced-motion: reduce) {
.panel {
transition: none;
}
}Principios clave para recordar
- La altura es una propiedad de diseño, así que animarla puede perder fotogramas
- Mide el contenido o recorta una transformación en lugar de animar auto
- Desvanece el contenido en vez de deslizar párrafos
- Abrir puede ser más lento que cerrar
- Mantén aria-expanded y el acceso por teclado durante toda la transición
Preguntas frecuentes
Fuentes
- Accordion Pattern — W3C WAI-ARIA Authoring Practices
- Animation performance and frame rate — web.dev
- prefers-reduced-motion — MDN Web Docs