JavaScript convirtió los documentos estáticos en software. Las aplicaciones de una sola página se sienten instantáneas. Sin recargas completas de página, sin parpadeos de pantallas blancas. Pero esa velocidad tiene un costo que muchos equipos ignoran: la maquinaria básica de la web comienza a pudrirse. La navegación se vuelve frágil. Los motores de búsqueda tienen dificultades para seguir las rutas. Los lectores de pantalla se pierden. Y los usuarios se encuentran atrapados en interfaces que parecen sitios web pero se comportan como aplicaciones de escritorio defectuosas.

El culpable suele ser un div con un manejador onClick.

Deja de usar divs como enlaces

Un div no tiene significado semántico. Es una caja. Cuando le añades un manejador de clic y lo usas para redirigir a los usuarios a una nueva vista, le estás pidiendo al navegador que trate una caja de cartón como si fuera una puerta. El navegador se niega. También lo hacen todas las herramientas construidas alrededor del navegador.

Los lectores de pantalla no anuncian un div como un enlace o un botón. Lo pasan por alto o lo leen como texto plano. Un usuario que navega por voz no puede seleccionarlo. Un rastreador de motores de búsqueda, al escanear tu página en busca de URLs descubribles, no ve nada que seguir. Tu ruta bien podría no existir.

Peor aún, pierdes los comportamientos que los usuarios ya conocen. Un enlace real permite que alguien haga clic derecho para abrir en una nueva pestaña, marque el destino como favorito o copie la dirección para compartirla. Los usuarios de teclado esperan presionar Tab para llegar a él y Enter para abrirlo. Un div no ofrece nada de esto. Incluso si le añades tabIndex, role="link" y escuchadores de teclado, estás reconstruyendo, y de forma deficiente, lo que el navegador te ofrece gratis. Y olvidarás algún caso extremo. Siempre lo haces.

Usa anclas para destinos y botones para acciones

HTML ya resolvió esto.

Stop. This is not a URL. It gives the browser no destination. It pollutes the history stack with unusable states. It breaks browser history and accessibility. It is a trap. If you need click behavior without navigation, you need a <button>. Style it to look however you want. CSS does not care whether the element is a button or a link. Your users do.

Write Text That Explains Where the User Is Going

The words inside your link matter. Screen reader users often pull up a list of every link on the page to scan quickly. If your links all say "Read more" or "Click here," that list becomes useless noise.

Be specific. Compare these:

  • Bad: <a href="/security/api-guide">Read more</a>
  • Good: <a href="/security/api-guide">Read the API security guide</a>

The second tells the user exactly what they will find. It gives search engines context about the destination page. It makes your link list navigable. Descriptive link text is one of the cheapest accessibility wins you can earn.

Test Like You Mean It

Architecture means nothing if you do not verify it.

First, test your keyboard flow. Unplug your mouse. Tab through every interactive element on your site. Every genuine link must show a visible focus outline, not a subtle glow that disappears against your background, but a clear ring that a tired eye can spot. Press Enter. It must activate the link. If Tab skips an element, or if Enter does nothing, you have a bug.

Second, test your routes at the server level. Client-side routing is a thin veneer. If a user bookmarks /dashboard/reports and returns tomorrow, or hits refresh, your server must know how to serve that page. Configure your reverse proxy or your server framework to fall back to your application shell for unknown paths, or serve the correct HTML directly. A dead 404 on refresh is not a minor bug. It is a broken promise.

JavaScript is a powerful layer