- En una interfaz web, usar
<button> en lugar de <div> es la opción correcta tanto en accesibilidad como en funcionalidad
<div> no es reconocido por los lectores de pantalla como un elemento interactivo y tampoco responde al foco del teclado ni a las teclas Enter y Spacebar
- Incluso si se agregan atributos como
[role="button"] o [tabindex="0"], siguen existiendo problemas con el orden del foco y el manejo de eventos de teclado
- Para resolver esos problemas, agregar varios event listeners y condicionales introduce una complejidad innecesaria
<button> ya incluye por defecto accesibilidad, foco y manejo de entrada por teclado, por lo que es una solución simple y estándar
Enfoque incorrecto: crear un botón con <div>
- Entre usuarios de React o HTMX, es común ver casos donde se implementan interacciones como abrir un modal con algo como
<div onclick="...">
- Problemas de este enfoque
- Los lectores de pantalla no reconocen ese elemento como interactivo
- No se puede mover el foco con el teclado
- Solo funciona el evento
click, y no responde a Enter ni a Spacebar
Límites de los intentos de “arreglar” la accesibilidad
Funciones integradas que ofrece <button>
Conclusión: la simplicidad es lo mejor
<button> es la forma más simple de cumplir con los estándares de accesibilidad y al mismo tiempo reducir la cantidad de código
- Usar elementos HTML estándar sin agregar atributos ni manejar eventos innecesarios favorece el mantenimiento y la eficiencia
- Con el mensaje de que “cuanto más flojo sea el desarrollador, más debería usar el elemento correcto”,
se enfatiza la importancia de adquirir el hábito de evitar complejidad innecesaria y aprovechar las funciones integradas
7 comentarios
Es un artículo muy bueno. La idea principal del texto se puede resumir como: “usemos las etiquetas HTML con significado”. Si damos eventos de clic con una etiqueta
div(o cualquier otra), creo que no hemos cambiado en nada con respecto a la época en que se armaban los layouts con etiquetastable.Claro, meter atributos
aria-*puede dejarlo más claro, pero ya que vas a pasar por todo ese trabajo, mejor usa la etiqueta adecuada jajajajaQué recuerdos jajaja
En los sitios web de las instituciones públicas de nuestro país parece que usan mucho
<a>...Comentarios de Hacker News
Una de mis quejas es que los sitios web implementan la navegación con manejadores
onclicksi simplemente usaran la etiqueta
<a>, abrir en una pestaña nueva, la integración con herramientas de accesibilidad, el menú de clic derecho y todo lo demás funcionarían automáticamentesi es navegación, deberían usar enlaces en lugar de una sopa de JavaScript
probablemente por influencia de los frameworks o por desinterés
aun así, la forma tradicional casi siempre es mejor en términos de UX
espero que quienes intentan reemplazar la etiqueta
<a>sufran aunque sea una pequeña incomodidadesa gente crea patrones incorrectos y los desarrolladores que vienen después simplemente los repiten
muy rara vez tuve que estilizar un
<div>para que pareciera un botónyo uso mucho el botón central del mouse para desplazarme, y muchos sitios rompen eso
con clic izquierdo abre una página de revisión de seguridad, pero con clic central simplemente te lleva directo
onClickhasta los elementos que en la práctica eran enlaces estaban manejados por handlers de clic, y no lo entiendo
La mayoría de los botones debería declarar
type="button"el valor predeterminado es
submit, así que si están dentro de un formulario se envían automáticamentesupongo que algunos desarrolladores no saben esto y por eso usan
<div>los botones con el tipo predeterminado se comportan de forma rara y a veces se saltan los handlers de JS
<input type="submit">, y<button>es distinto<div>, puedes evitar el problema detype="submit"un
<div>empieza vacío, así que puedes agregar solo la funcionalidad que necesitas y luego modificarla con facilidaden cambio, con
<button>tienes que leer la documentación para entender su comportamiento por defectoal final, es una cuestión de control explícito vs funcionalidad incorporada
Me gustaría que el artículo ampliara la idea de “usemos tal cual los elementos HTML creados para ese propósito”
muchos desarrolladores de SPA no entienden bien la semántica de los elementos HTML y reinventan la rueda cada vez
por ejemplo, el date picker predeterminado es tan feo que terminas reemplazándolo con uno basado en JS
por eso surgieron los botones personalizados
Hoy existe toda una generación que anda picándole a la pantalla por todos lados para encontrar qué área se puede pulsar
hace 10 años alguien decidió que arrastrar enlaces era más importante que seleccionar texto, y ahora seleccionar texto es casi imposible
para arreglar eso tal vez habría que hacer un fork del navegador
si mantienes presionada la tecla Alt (u Option), puedes seleccionar el texto dentro del enlace
de verdad es un comportamiento no deseado
con la app TextSniper de macOS puedes seleccionar un área y copiar el texto con OCR
gracias a eso incluso Google Analytics se vuelve un poco más usable
este problema debería mencionarse más seguido
antes había una llamada Select Like A Boss, y ahora se llama Drag-Select Link Text
La hoja de estilo predeterminada de Chrome tiene
button {align-items: flex-start}, y por eso me perdí mucho tiempo con un bug de tamaño en flexboxaun así, trato de usar los elementos HTML correctos siempre que puedo, aunque en proyectos personales pequeños a veces
<div>resulta más cómodoappearance: nonees útil para resetear el estilo de los botonesyo hice una clase
.unbuttonifypara que se comporten como botón pero tengan otra aparienciaSiempre que se pueda, hay que usar los elementos de acuerdo con su propósito original
Tengo dos quejas sobre los botones
una es que de todos modos hay que volver a darles estilo,
y la otra es la advertencia de que no se pueden anidar botones
en la práctica, esto se encuentra con bastante frecuencia
Los LLM generan con frecuencia este tipo de patrones incorrectos
muchas veces ignoran las funciones predeterminadas del navegador e implementan soluciones complicadas
yo suelo pedirle a Claude que simplifique ese tipo de código
en TypeScript también tienden a hacer rara la forma de manejar errores
Yo procuro usar botones por defecto siempre que sea posible
eso sí, si en realidad debe comportarse como un enlace, uso la etiqueta
<a><a>Me preguntaba por qué alguien querría usar
<div><div>facilita una personalización visual extrañay así termina sin parecer ni funcionar como botón
<div onclick>background, border, outline, appearance, -webkit-appearance, cursor
Hay demasiadas hojas de estilo predeterminadas que hay que sobrescribir, snif snif
Por eso existe el CSS Reset.