lunes, 24 de septiembre de 2007

Enlaces que actúan como botones. Implementación accesible.

Artículos relacionados
[19-07-07] Formulario con varios botones. Implementación usable y accesible.
[28-02-08] Formularios usables: 60 Directrices de Usabilidad
[28-03-12] Detectar si una imagen se ha cargado. Descripción extensa de una imagen: accesible con lector de pantalla y visible sin imágenes activas


A menudo nos encontramos con enlaces que actúan como botones, es decir, no enlazan con una nueva página u operativa en el "href", sino que este se deshabilita con "#", "void(0)" o "javascript:;" y se le asigna por ejemplo un "onclick" que realice una acción.

Encontramos este tipo de enlaces sustituyendo a los botones de un formulario, o aparecen en la última columna de una tabla para realizar alguna acción asociada a esa fila ("Editar", "Detalle", etc.), o en otros muchos contextos.

¿Necesitas por exigencias contra las que ya no puedes luchar que sean enlaces?... bueno, no pasa nada, pero hagámoslo bien.

Quiero hacer esto


Vamos a imaginar el siguiente ejemplo: tenemos un formulario muy simple, con un único campo "Nombre" que queremos enviar mediante un enlace "Enviar".

Su aspecto sería el siguiente:
Ejemplo visual del formulario descrito

¿Qué nos podemos encontrar?


Veamos varias variantes. NINGUNA de ellas es accesible:
1.
<a href="javascript:enviar()">Enviar</a>

2.
<a href="#" onclick="enviar()">Enviar</a>

3.
<a href="javascript:void(0)" onclick="enviar()">Enviar</a>

4.
<a href="javascript:;" onclick="enviar()">Enviar</a>

5.
<a href="javascript:;" onclick="enviar()" onkeypress="enviar()">Enviar</a>

6.
<a href="javascript:;" id="enlaceEnviar">Enviar</a>

Todas ellas llaman a la función enviar() que somete el formulario:

function enviar(){document.miform.submit()}

Salvo la versión 6, que se han molestado en implementar javascript no-intrusivo.

document.getElementById("enlaceEnviar").onclick=function (){document.miform.submit()}

¿Por qué ninguna de estas opciones es accesible?


Porque todas dependen de que el navegador del usuario admita javascript o lo tenga activo. En caso contrario no funcionará.

¿Cuál es entonces la solución?


Pues si Mahoma no va a la montaña...
¿Por qué empeñarnos en hacer enlaces que actúen como botones? ¿Por qué no hacemos botones que parezcan enlaces?

<input type="submit" name="enviar" id="enviar" value="Enviar" class="enlace" />

Este botón tendrá el mismo aspecto que nuestro enlace tan sólo con que definamos su clase "enlace" (en la CSS) de esta manera:

input.enlace{border:0; background-color:#fff; text-decoration:underline; color:#000; cursor:pointer;}

¿Por qué algo tan sencillo y limpio no se encuentra nunca?

Nota: si necesitas tener varios botones que actúen de esta manera, quizás deberías leer Formulario con varios botones. Implementación accesible.

Artículos relacionados
[19-07-07] Formulario con varios botones. Implementación usable...
[28-02-08] Formularios usables: 60 Directrices de Usabilidad
[28-03-12] Detectar si una imagen se ha cargado. Descripción extensa de una imagen: accesible con lector de pantalla y visible sin imágenes activas

21 comentarios :
Acido 69 dijo...

perdona, no quiero parecer grosero. Pero sera que esta opción es bastante natural, quiero decir que si lo que quieres es anular el fondo del botón es tan simple como quitar el estilo que tiene????

Olga Carreras dijo...

Claro que es obvio, la pregunta es: ¿por qué nadie lo hace? ¿por qué todo el mundo opta por poner los enlaces tipo href="javascript:;" onclick="" que son inaccesibles en vez de poner botones?

xavi dijo...

yo diría que es una práctica habitual para muchos.

una pequeña consideración: para que sean exactamente iguales, deberías eliminar el efecto de pulsación de botón (que no tiene el enlace).

he trabajado con varios diseñadores que preguntan: ¿pq este enlace se mueve al pulsar y el resto no?

supongo que los usuarios se harán la misma pregunta =)

Juan_Pablo dijo...

¡Pero un link con javascript si puede ser usable y accesible! por ejemplo, para abrir una nueva ventana, yo lo hago así:

href="dirección/de/la/página" onclick="openEditor(this.href);return false;"
target="_blank"

de esa forma se puede incluso abrirla en una pestaña con un Ctrl+click

En otros casos.. .pues

Olga Carreras dijo...

Juan Pablo, ese ejemplo sirve como alternativa a un script que abra un pop-up, pero no sirve para enviar un formulario, para enviar un formulario debes hacer un submit.

Olga Carreras dijo...

Xavi, tienes razón, pero creo que es mejor eso a que algunos usuarios no puedan interactuar con la página.

Siempre nos queda convencer al cliente (que es el único que se puede empeñar en estas cosas) en que lo correcto es un botón.

ramonono | Maeghith dijo...

----
¿por qué todo el mundo opta por poner los enlaces tipo href="javascript:;" onclick="" que son inaccesibles en vez de poner botones?
----
Por un lado, creo que dreamweaver pone algunos así por defecto en no se qué caso exactamente.

Por otro lado, no veo inconveniente para "acciones idempotentes" que accedan a recursos REST (vamos, si la petición es un GET, que no hace ninguna "acción peligrosa" como borrar registros de la BBDD) pero claro, ¿para qué usar JS entonces si se va a acceder a una URL normal? (¿goto dreamweaver? :-/ ).

Por otro lado tienes que con el manido temita del AJAX cualquier enlace es candidato a realizar alguna acción. Esto puede causar confusión ("¿esto lo hago con enlace?"), o inercia ("acabo de poner un enlace con JS, y no me viene como poner la cosa esa de los formularios").

Y para terminar, poniendonos pejigueros, ¿por qué usar 'input' para un botón cuando puedes usar 'button'? ;)

Olga Carreras dijo...

Ramono, hay una buena razón para usar "input" en vez de "button", la pongo en el post "Formulario con varios botones. Implementación accesible".

Básicamente se puede resumir en que "button" funciona mal en Explorer, puedes ampliar más información en "Button Hell"

Nordic dijo...

De todas maneras, antes de intentar convencerlo para utilizar una de estas formas accesibles, lo intentaría convencer de que utilice las cosas para lo que son:

1) Los links son para navegar entre páginas.
2) Las acciones se muestran como un botón.

Es una simple cuestión de usabilidad.

ramonono | Maeghith dijo...

sí, bueno, algunos no consideramos que explorer sea una buena razón XD

Lester dijo...

EL "efecto botón" se puede eliminar manejando también el estilo del botón al pasar el mouse.
O sea, además de

#boton {}

manejar también

#boton:hover { }


Otra cosa. Los estilos a los boones de formularios (input de tipo submit o rset) no funcionan en ms internet explorer 6.

LESTER FIBLA SAAVEDRA
www.lesterfibla.com

Olga Carreras dijo...

Nordic, en eso estamos de acuerdo.

Ramonono, ¿entonces haces una aplicación pasando de la inmensa cantidad de usuarios que usan Explorer? Uno puede pensar lo que quiera d eun navegador, pero debe respetar a todos los usuarios que lo usan... y sino ya se encargará tu cliente de que los respetes... normalmente tiene un Explorer.

Lester, la solución es que un botón tenga un aspecto de enlace, pero no es un enlace, esa es la gracia, así que el a.hover no se aplica.

En cuanto a que en Explorer 6 no se aplican los estilos a los botones, pues como no tengas un Explorer 6 extraterreste, me temo que los estilos en los botones SI se aplican.

Israel dijo...

y si hay que validar lo que se escribe el campo de texto?

Olga Carreras dijo...

No problem, Israel, puedes validar los campos de un formulario por javascript siempre y cuando la validación la hagas también en el servidor, en el caso de que el usuario no tenga activo el javascript, se ignorará la validación por javascript, se enviará el formulario, se validarán los campos en el servidor y en caso de que haya errores recargará la página del formulario indicando adecuadamente los errores que hubo.

El mismo comportamiento que en la validación javascrit sólo que recargando la página.

ramonono | Maeghith dijo...

Imagino que te suena la idea de educar al usuario.

Pues por las buenas, o por las malas ;)

PD: Evidentemente hay usuarios menos educables. Se hace lo que se puede.

PPD: No te tomes muy en serio los comentarios que he puesto los smileys para eso (¿asperger digital?), aunque a lo mejor soy yo el que está tomandose demasiado en serio tus respuestas :-7

PPPD: Tampoco lo he dicho antes, pero el artículo está muy bien. Y las respuestas también.

Olga Carreras dijo...

Ramonono, a los usuarios no hay que educarlos, hay que educar a los clientes y a los desarrolladores.

Y aunque conteste de forma directa es muy amistosa :-)) de hecho me encanta que os hayais molestado en darme un poco de vidilla con vuestros comentarios.

Anónimo dijo...

ok.. ok.. muy de acuerdo con eso de usar las cosas para lo que son.. pero el echo es que un boton no se comporta igual que un link.. por mas que a simple vista lo paresca.. es decir.. para empezar no podemos seleccionar el texto dentro de un boton.. y lo otro.. si tenemos un fondo detras del texto (boton )?...el boton no es transparente.. asi ke se veria un cuadro extraño rodeando lo que se supone que es un texto..
si creo ke se deberia usar un boton.. pero si nuestra intencion es que paresca parte del texto (un link)?? y que sea seleccionable el texto??

porquero dijo...

Acá hay una solucion que creé, es compatible con la mayoría de los navegadores y es accesible:
Botones accesibles

Anónimo dijo...

A mi me parecio Interesante no se lo que otros Digan...porque yo estoy aprendiendo y como no sabia como pasar el valor de unas variables entre varias paginas php haciendo clicks en links me toco ocultar unas cajas de texto con los valores que queria y luego enviar el valor dando clicks en los "Links".

Saludos y Gracias...

Anónimo dijo...

Comentar que la alternativa que das falla al pasar el test de la w3c con las CSS. Se debe sustituir el cursor:hand por cursor:pointer; (añadiendo el punto y coma)

Saludos

Luis Puerto dijo...

No tenia ni idea de esta solución y me ha servido para poner un enlace con letra pequeñita en un "div" estrecho, en el que me quedaba muy feo un boton "input" normal.
Muchas gracias por la ayuda.
Saludos desde Zaragoza.

Publicar un comentario en la entrada