Accordion & FAQ
Accordion & FAQ
8 reglasSingle-open para secuencial; multi-open para comparativo
El modo de apertura del accordion debe coincidir con la tarea cognitiva del usuario. En flujos donde el contenido es secuencial y no necesita comparación simultánea (onboarding, tutoriales, configuración paso a paso), single-open reduce la carga cognitiva al mantener solo un bloque visible. En contextos comparativos donde el usuario necesita ver dos respuestas al mismo tiempo (FAQ técnica, tabla de características, opciones de producto), multi-open es la elección correcta. Forzar single-open en un FAQ comparativo obliga al usuario a memorizar el contenido del panel anterior antes de abrir el siguiente, aumentando los errores de decisión. La elección del modo debe documentarse en el diseño del componente, no dejarse al azar.
NN/g "Accordions Are Not Always the Answer" 2014 · ARIA Authoring Practices Guide 1.2 · Apple HIG Disclosure Controls · Radix UI AccordionAnimar con grid-template-rows: 0fr → 1fr; nunca max-height hack
La técnica de max-height para animar alturas en accordions produce tres problemas: clipping visual al inicio de la transición si el valor máximo es demasiado bajo, retardo perceptible al final si es demasiado alto (el elemento ya alcanzó su tamaño real pero la transición continúa), y un recálculo de layout por frame que impacta el rendimiento en dispositivos móviles. La alternativa correcta usa grid-template-rows: 0fr en el estado cerrado y 1fr en el abierto; combinado con overflow: hidden en el contenedor interior, logra una animación suave de altura real sin los artificios del hack. El soporte en navegadores modernos supera el 95% desde 2023. Esta técnica es utilizada por Radix UI, shadcn/ui y Headless UI en producción.
Chevron 180°; toda la barra header = tap target mínimo 44px
El chevron rotando 180° es el indicador de estado más universal en accordions: el usuario aprende una vez y predice el comportamiento en cualquier implementación futura. La dirección convencional es hacia abajo en estado cerrado (▾), hacia arriba en estado abierto (▴). El tap target debe cubrir la barra completa: hacer clickeable solo el chevron es un error frecuente que genera errores de selección, especialmente en dispositivos táctiles. WCAG 2.5.5 requiere mínimo 44×44px para controles táctiles, un header de accordion puede ser visualmente más delgado pero su área interactiva debe cumplir este mínimo con padding compensatorio. En desktop, el cursor debe cambiar a pointer sobre toda la barra, no solo sobre el texto o el ícono.
aria-expanded en button; role=region solo si ≤6 paneles; aria-controls para JAWS
El patrón accesible de accordion requiere que el elemento interactivo sea un <button> nativo con aria-expanded="true/false" que cambia dinámicamente. El aria-controls apunta al ID del panel y es crítico para JAWS, el screen reader de escritorio más usado en entornos corporativos; sin él, JAWS no puede saltar directamente al panel expandido. El atributo role="region" debe añadirse al panel solo cuando hay 6 paneles o menos: con más paneles, los puntos de navegación por landmarks se vuelven contraproducentes y fragmentan la experiencia en VoiceOver y NVDA. El panel debe identificarse con aria-labelledby apuntando al ID del botón, creando el vínculo semántico bidireccional. Nunca usar <div> ni <a> para el trigger de accordion.
Panel oculto con display:none o hidden; NUNCA visibility:hidden
Hay tres formas comunes de ocultar el panel de un accordion y solo dos son correctas. display:none y el atributo hidden eliminan el elemento del flujo de layout y del árbol de accesibilidad, de modo que el screen reader no anuncia el contenido colapsado. visibility:hidden es el anti-patrón: oculta visualmente el elemento pero lo mantiene en el flujo de layout (el espacio queda reservado), y lo más grave es que los links y controles dentro del panel siguen siendo enfocables con Tab aunque sean invisibles, creando "foco fantasma" para usuarios de teclado. Para la técnica de animación grid-rows, el inner wrapper lleva hidden cuando el accordion está cerrado y se lo quita con JavaScript justo antes de iniciar la transición de apertura.
FAQ: headings semánticos + JSON-LD FAQPage schema
Un accordion de FAQ debe usar headings semánticos reales (<h2> o <h3>) como contenedor del botón trigger, creando una jerarquía de documento navegable por screen readers y bots. Esto permite que el usuario de lector de pantalla navegue entre preguntas con el atajo de heading en lugar de tabular a cada botón individualmente. Adicionalmente, el JSON-LD FAQPage es el schema más adoptado en Rich Results de Google: cuando está correctamente implementado, Google puede mostrar las preguntas y respuestas expandidas directamente en la SERP, aumentando el CTR orgánico entre un 20% y 30% según datos de Search Console. El schema no requiere que el accordion esté técnicamente visible en la página; Google lee el JSON-LD independientemente del estado del componente.
h3¿Cuánto dura la garantía?
h3¿Puedo devolver el producto?
Nunca ocultar info crítica para la decisión de compra
El accordion es una herramienta de organización de información secundaria, no un lugar para esconder datos que el usuario necesita para decidir. Precio, condiciones de envío, restricciones de uso y avisos legales relevantes deben estar siempre visibles en el flujo de la página, sin requerir interacción del usuario para descubrirlos. Según estudios de Baymard Institute, el 16% del abandono en checkout se produce cuando los usuarios descubren costos adicionales que no eran visibles en la página de producto. El accordion correcto contiene especificaciones técnicas, preguntas frecuentes o información de soporte, contenido relevante solo para un subconjunto de usuarios. Si el contenido es necesario para que cualquier usuario tome una decisión informada, no va en accordion.
Baymard Institute "Checkout Usability" 2023 · NN/g "Progressive Disclosure" · FTC "Clear and Conspicuous Disclosures" · Luke Wroblewski "Mobile First" · Amazon Checkout A/B TestsMáx 1 nivel; nunca split target (título navega / chevron expande)
Un accordion anidado, donde el panel abierto contiene otro accordion, duplica la complejidad cognitiva sin añadir capacidad real de organización: si el contenido requiere dos niveles de jerarquía, la solución correcta es refactorizar a un sistema de navegación (sidebar + páginas). El anti-patrón del split target es igualmente grave: ocurre cuando el título del accordion es un enlace que navega a una página mientras el chevron colapsa/expande el panel. El resultado son dos zonas de interacción diferentes en el mismo elemento con comportamientos incompatibles. El usuario que hace click en el título espera expandir el panel, no navegar, porque así funciona el 99% de los accordions que ha usado antes. Toda la barra debe ser un único <button> nativo con una sola acción predecible.
- R-122 Single-open para secuencial; multi-open para comparativo
- R-123 Animar con grid-template-rows: 0fr → 1fr; nunca max-height hack
- R-124 Chevron 180°; toda la barra header = tap target mínimo 44px
- R-125 aria-expanded en button; role=region solo si ≤6 paneles; aria-controls para JAWS
- R-126 Panel oculto con display:none o hidden; NUNCA visibility:hidden
- R-127 FAQ: headings semánticos + JSON-LD FAQPage schema
- R-128 Nunca ocultar info crítica para la decisión de compra
- R-129 Máx 1 nivel; nunca split target (título navega / chevron expande)