Técnica Scripts de cliente WCAG 2.2
SCR35Asociar las acciones de JavaScript a botones y enlaces
Nombre oficial en el W3C: Hacer accesibles por teclado las acciones usando el evento onclick de enlaces y botones
En pocas palabras
Cuando un script hace algo al pulsar un control, ese control debe ser un botón o un enlace de verdad. Estos elementos reciben el foco, y su evento click se lanza también con el teclado. Así la acción funciona igual con ratón, con teclado y con lectores de pantalla.
Por qué es importante
Muchas webs ponen el evento de clic en un div, un span o una imagen. Con ratón funciona, pero esos elementos no reciben el foco ni responden a las teclas.
Quien navega con teclado, con un lector de pantalla (programa que lee en voz alta lo que hay en la pantalla) o con un pulsador no puede activar la acción. Por ejemplo, no podría ver el horario de una oficina ni añadir un producto a la cesta.
Cómo se hace
- Si la acción cambia algo en la página (mostrar, ocultar, añadir, calcular), use
<button type="button">. - Si lleva a otro sitio, use un enlace
<a>conhref. Sinhrefno recibe el foco. - Asocie el script al evento
click. Aunque el nombre sugiera el ratón, también se lanza con el teclado: con Intro en los enlaces y con Intro o Espacio en los botones. - No lance la acción con eventos solo de ratón, como
mousedownomouseover. - Si la página debe funcionar sin JavaScript, dé una alternativa. Puede ser un
hrefa una página con la misma función o un formulario que se envíe al servidor. - Si el botón es una imagen (
<input type="image">), póngale unaltque diga qué hace.
Ejemplo práctico
Ficha de una oficina municipal con un control que muestra u oculta el horario de atención. Es frecuente hacerlo con un div que responde al clic, en lugar de con un botón.
Así no: Un div con onclick que hace de botón
El div responde al clic del ratón. Pero no recibe el foco ni reacciona a Intro o Espacio: con teclado no hay forma de ver el horario. Además, el lector de pantalla lo lee como texto normal, no como un control.

La demostración contiene, a propósito, el error de accesibilidad que se explica.
Ver el código del ejemplo incorrecto
<h2>Oficina de Atención Ciudadana</h2>
<div class="accion" onclick="verHorario(this)">Ver horario de atención</div>
<p id="horario" hidden>De lunes a viernes, de 9:00 a 14:00. Jueves, también de 16:30 a 18:30.</p>
<style>
h2 { font-size: 1.1em; }
.accion { display: inline-block; background: #744E9A; color: #fff; border: 0; padding: .5em 1em; font: inherit; cursor: pointer; }
</style>
<script>
function verHorario(control) {
var horario = document.getElementById('horario');
horario.hidden = !horario.hidden;
}
</script>Así sí: La misma acción en un botón de verdad
El control pasa a ser un <button type="button">. Recibe el foco, su evento click también se lanza con Intro y con Espacio, y se anuncia como botón. Como abre y cierra un contenido, lleva aria-expanded, que indica si está abierto.
Pruébelo aquí:
Ver el código del ejemplo correcto
<h2>Oficina de Atención Ciudadana</h2>
<button type="button" class="accion" aria-expanded="false" aria-controls="horario" onclick="verHorario(this)">Ver horario de atención</button>
<p id="horario" hidden>De lunes a viernes, de 9:00 a 14:00. Jueves, también de 16:30 a 18:30.</p>
<style>
h2 { font-size: 1.1em; }
.accion { display: inline-block; background: #744E9A; color: #fff; border: 0; padding: .5em 1em; font: inherit; cursor: pointer; }
.accion:focus-visible { outline: 3px solid #0B2239; outline-offset: 2px; }
</style>
<script>
function verHorario(control) {
var horario = document.getElementById('horario');
horario.hidden = !horario.hidden;
control.setAttribute('aria-expanded', String(!horario.hidden));
}
</script>Cómo comprobarlo
Errores frecuentes en auditorías
- Usar div o span con onclick como botones: no reciben el foco ni responden a Intro o Espacio.
- Añadir tabindex="0" a un div clicable sin programar Intro y Espacio: recibe el foco, pero no hace nada.
- Usar un enlace a sin href para lanzar scripts: sin href no recibe el foco ni se activa con teclado.
- Lanzar la acción con mousedown o mouseup en lugar de click: el teclado no dispara esos eventos.
Ver el texto completo del W3C (traducción al español)
Esta es una traducción no oficial al español de la técnica SCR35 de Techniques for WCAG 2.2, del W3C. Puede contener errores. El único documento oficial y normativo es la versión original en inglés, publicada en el sitio web del W3C.
Aplicabilidad
Scripts usados con HTML.
Descripción
El objetivo de esta técnica es mostrar cómo invocar una función de script de forma accesible por teclado, asociándola a un control accesible por teclado. Para garantizar que las acciones de script puedan invocarse desde el teclado, se asocian a elementos HTML «accionables de forma nativa» (enlaces y botones). El evento onclick de estos elementos es independiente del dispositivo. Aunque «onclick» suena a que está ligado al ratón, en realidad el evento onclick está asociado a la acción predeterminada de un enlace o de un botón. La acción predeterminada se produce cuando el usuario hace clic en el elemento con el ratón, pero también cuando el usuario sitúa el foco en el elemento y pulsa Intro o Espacio, y cuando el elemento se activa a través de la API de accesibilidad.
Esta técnica depende de los scripts del lado del cliente. No obstante, es beneficioso proporcionar una implementación alternativa o una explicación para los entornos en los que los scripts no estén disponibles. Cuando se usan elementos de anclaje para invocar una acción JavaScript, la implementación alternativa o la explicación se proporciona mediante el atributo href. Cuando se usan botones, se proporciona mediante el envío de un formulario.
Ejemplos
Enlace que ejecuta un script y no tiene alternativa para navegadores sin scripts
Este enfoque solo debe usarse cuando se confía en los scripts como tecnología compatible con la accesibilidad.
Aunque no queremos navegar desde este enlace, debemos usar el atributo href en el elemento a para que sea un verdadero enlace y obtenga el tratamiento de eventos adecuado. En este caso usamos href="#" como destino del enlace, pero podría usarse cualquier cosa. Nunca se navegará por este enlace.
El «return false;» al final de la función de manejo de eventos doStuff() indica al navegador que no navegue al URI. Sin él, la página se recargaría después de ejecutarse el script.
<script>
function doStuff() {
//do stuff
return false;
}
</script>
<a href="#" onclick="return doStuff();">do stuff</a>
Enlace que ejecuta un script, pero navega a otra página cuando los scripts no están disponibles
Este enfoque puede usarse para crear sitios que no dependan de los scripts, siempre y cuando el destino de la navegación ofrezca la misma funcionalidad que el script. Este ejemplo es idéntico al ejemplo 1, salvo que ahora su href apunta a una página real, dostuff.html. La página dostuff.html debe ofrecer la misma funcionalidad que el script. El «return false;» al final de la función de manejo de eventos doStuff() indica al navegador que no navegue al URI. Sin él, el navegador navegaría a dostuff.html después de ejecutarse el script.
<script>
function doStuff() {
//do stuff
return false;
}
</script>
<a href="dostuff.html" onclick="return doStuff();">do stuff</a>
Hay disponible un ejemplo funcional de este código. Consulte Creating Action Links using JavaScript (crear enlaces de acción con JavaScript).
Botón que ejecuta un script y recurre al envío de un formulario para los usuarios sin scripts
Este enfoque pueden usarlo los sitios que no dependen de los scripts, siempre y cuando el envío del formulario ofrezca la misma funcionalidad que el script. El onsubmit="return false;" impide que se envíe el formulario.
<script>
function doStuff() {
//do stuff
}
</script>
<form action="doStuff.aspx" onsubmit="return false;">
<input type="submit" value="Do Stuff" onclick="doStuff();">
</form>
Hay disponible un ejemplo funcional de este código. Consulte Creating Action Buttons using JavaScript (crear botones de acción con JavaScript).
Botón que ejecuta un script, implementado con input type="image"
Tenga en cuenta que debe añadirse un atributo alt al input para proporcionar un equivalente textual de la imagen. Este enfoque solo debe usarse cuando se confía en los scripts.
<script>
function doStuff() {
//do stuff
return false;
}
</script>
<input type="image" src="stuff.gif" alt="Do stuff" onclick="return doStuff();">
Botón que ejecuta un script, implementado con input type="submit", input type="reset" o input type="button"
Este enfoque solo debe usarse cuando se confía en los scripts.
<input type="submit" onclick="return doStuff();" value="Do Stuff">
Botón que ejecuta un script, implementado con button
Esto resulta útil cuando se desea más control sobre el aspecto del botón. En este ejemplo concreto, el botón contiene tanto un icono como texto. Este enfoque solo debe usarse cuando se confía en los scripts.
<button onclick="return doStuff();">
<img src="stuff.gif" alt="stuff icon">
Do Stuff
</button>
Pruebas
Procedimiento
Para todas las acciones de script asociadas a elementos a, button o input:
-
En un agente de usuario compatible con scripts
- Hacer clic en el control con el ratón.
- Comprobar que la acción del script se ejecuta correctamente.
- Si el control es un elemento de anclaje, comprobar que no se invoca el URI del atributo
hrefdel elemento de anclaje. - Comprobar que es posible navegar hasta el control y darle el foco mediante el teclado.
- Situar el foco del teclado en el control.
- Comprobar que al pulsar INTRO se invoca la acción del script.
- Si el control es un elemento de anclaje, comprobar que no se invoca el URI del atributo
hrefdel elemento de anclaje.
-
En un agente de usuario no compatible con scripts
- Hacer clic en el control con el ratón.
- Si el control es un elemento de anclaje, comprobar que se invoca el URI del atributo
hrefdel elemento de anclaje. - Comprobar que es posible navegar hasta el control y darle el foco mediante el teclado.
- Situar el foco del teclado en el control.
- Si el control es un elemento de anclaje, comprobar que al pulsar INTRO se invoca el URI del atributo
hrefdel elemento de anclaje.
Resultados esperados
- Todas las comprobaciones anteriores son verdaderas.
Recursos
-
HTML - the
scriptelement (especificación HTML: el elemento script) - HTML - Forms (especificación HTML: formularios)
-
HTML - the
aelement (especificación HTML: el elemento a)
Cómo lo comprobamos en ADDAW
En cada auditoría de ADDAW revisamos esta técnica página a página y le entregamos los errores con capturas y la forma de corregirlos.
Basado en la técnica SCR35 del W3C (WCAG 2.2). Explicación y ejemplos: ADDAW. Traducción no oficial del texto del W3C © W3C, licencia de documentos del W3C. ¿Ha visto un error? Escríbanos.