Acerca de esta regla de accesibilidad
HTML tiene un modelo de contenido claro: los elementos interactivos como <button>, <a>, <select>, e <input> no pueden contener otros elementos interactivos o enfocables. Cuando anidas un control interactivo dentro de otro — por ejemplo, colocando un enlace dentro de un botón — los navegadores y las tecnologías asistivas manejan la situación de manera inconsistente e impredecible.
Los lectores de pantalla se ven especialmente afectados. Cuando un usuario presiona tab para llegar a un elemento interactivo anidado, el lector de pantalla puede producir una parada de tabulación vacía o silenciosa. El nombre, rol y estado del control interno no se anuncian, lo que significa que el usuario no tiene idea de qué hace el control o de que incluso existe. Esto crea una barrera seria para usuarios ciegos que dependen de lectores de pantalla y usuarios que solo usan teclado que navegan mediante tabulación a través de elementos enfocables.
Este problema también afecta a usuarios con discapacidades motoras que usan dispositivos de conmutación u otros métodos de entrada asistiva que dependen de una comprensión precisa de los elementos interactivos en la página.
Criterios de éxito WCAG relacionados
Esta regla se corresponde con el Criterio de éxito 4.1.2 de WCAG 2.0, 2.1 y 2.2: Nombre, función, valor (Nivel A). Este criterio requiere que para todos los componentes de la interfaz de usuario, el nombre y la función puedan determinarse programáticamente, y los estados, propiedades y valores que puedan ser establecidos por el usuario puedan establecerse programáticamente. Los controles interactivos anidados violan esto porque el nombre y función del control interno se vuelven inaccesibles para la tecnología asistiva.
Cómo solucionarlo
La solución es directa: no coloques elementos enfocables o interactivos dentro de otros elementos interactivos. Aquí tienes estrategias comunes:
- Separa los controles. Coloca los elementos interactivos uno al lado del otro en lugar de anidarlos.
- Reestructura el diseño. Si un diseño requiere una tarjeta clickable con enlaces o botones internos, usa posicionamiento CSS o delegación de eventos JavaScript en lugar de anidación literal.
-
Revisa elementos con roles ARIA. Un
<div>conrole="button"se trata como un control interactivo. No debe contener enlaces, botones, inputs o cualquier otro elemento enfocable.
Ejemplos
Incorrecto: enlace anidado dentro de un botón
El elemento <a> dentro del <button> crea un control interactivo anidado que los lectores de pantalla no anunciarán correctamente.
<button>
Guardar
<a href="/options">Más opciones</a>
</button>
Incorrecto: enlace anidado dentro de un elemento con role="button"
Aunque el elemento externo es un <div>, el role="button" lo convierte en un control interactivo. El <a> anidado es inaccesible para los lectores de pantalla.
<div role="button" tabindex="0">
Buscar
<a href="/settings">Configuración</a>
</div>
Incorrecto: botón anidado dentro de un enlace
Colocar un <button> dentro de un elemento <a> es igualmente problemático.
<a href="/dashboard">
Ir al panel
<button>Configuración</button>
</a>
Correcto: controles interactivos separados
Coloca cada elemento interactivo independientemente para que ambos sean completamente anunciados y operables.
<button>Guardar</button>
<a href="/options">Más opciones</a>
Correcto: tarjeta clickable con controles separados
Si necesitas un patrón de tarjeta donde toda la tarjeta sea clickable pero también contenga acciones separadas, evita la anidación literal. Usa una estructura plana con CSS para el diseño.
<div class="card">
<h3><a href="/article/1">Título del artículo</a></h3>
<p>Una breve descripción del artículo.</p>
<button>Marcar</button>
</div>
Correcto: botón simple sin contenido interactivo anidado
Un botón simple, correctamente estructurado con solo contenido no interactivo dentro de él.
<button>
<svg aria-hidden="true" focusable="false">
<use href="#icon-save"></use>
</svg>
Guardar
</button>
Ten en cuenta que en el ejemplo anterior, el elemento <svg> tiene focusable="false" para evitar que sea una parada de tabulación en algunos navegadores (notablemente versiones anteriores de Internet Explorer y Edge), y aria-hidden="true" porque el texto del botón ya proporciona el nombre accesible.
Learn more:
Ayúdanos a mejorar nuestras guías
Detecta problemas de accesibilidad automáticamente
Rocket Validator escanea miles de páginas con Axe Core y el W3C Validator, encontrando problemas de accesibilidad en todo tu sitio web.