Yeda AI Tips · #110

English

outline: none sin un estilo de foco de reemplazo

Una sola línea de CSS está dejando silenciosamente a los usuarios de teclado fuera de tu app. outline: none sin reemplazo elimina el anillo de foco del navegador — la única señal visual que tiene un usuario de teclado para saber "estás aquí". En un flujo de login o de checkout, no es un bug cosmético: es una puerta cerrada con llave.

Por qué existe el anillo de foco

Cada elemento interactivo — enlaces, botones, inputs — recibe del navegador un contorno de foco por defecto. Los usuarios de teclado con visión (power users, personas con discapacidades motoras, cualquiera cuyo trackpad murió) recorren la página con Tab y dependen de ese anillo para saber qué elemento recibirá la próxima tecla. Si lo quitas, la página sigue funcionando, pero de forma invisible: el foco se mueve, nada cambia en pantalla y el usuario navega a ciegas.

La documentación de MDN sobre la propiedad outline es directa: si se elimina el estilo de foco por defecto, el elemento debe recibir un reemplazo evidente. WCAG codifica la misma regla en el criterio de éxito 2.4.7 Focus Visible (nivel AA): toda interfaz operable por teclado necesita un modo donde el indicador de foco sea visible.

No es un problema de nicho. El análisis 2026 de WebAIM sobre el millón de páginas de inicio más visitadas encontró fallas WCAG detectables en el 95.9% de ellas — un promedio de 56 errores por página. El foco invisible es uno de los contribuyentes clásicos, y suele entrar al código como un solo "reset" bien intencionado.

Por qué los equipos lo borran

Los diseñadores ven el anillo aparecer cuando el usuario hace clic en un botón y lo consideran feo. Eso pasa porque :focus coincide con cada evento de foco — mouse, touch y teclado por igual. El viejo arreglo era outline: none, que "resolvía" el caso del mouse rompiendo el caso del teclado.

El arreglo moderno: :focus-visible

:focus-visible coincide solo cuando el navegador decide que el usuario realmente necesita ver el foco — en la práctica: sí para navegación con teclado, no para clics de mouse en la mayoría de los controles. Es Baseline con soporte amplio en navegadores desde marzo de 2022. Eso permite tener los dos resultados a la vez:

/* 1. Quiet the ring for pointer clicks */
:focus:not(:focus-visible) {
  outline: none;
}

/* 2. Give keyboard users a real indicator */
:focus-visible {
  outline: 2px solid currentColor;
  outline-offset: 2px;
}

currentColor mantiene el anillo alineado con la marca automáticamente (hereda el color del texto del elemento), outline-offset agrega espacio para que el anillo no quede pegado al borde, y los outlines no cuestan nada en layout — no ocupan espacio y hasta siguen el border-radius en navegadores modernos.

Reglas prácticas

SituaciónHaz esto
El anillo aparece al hacer clic con el mouseEstiliza :focus-visible, no :focus
outline: none heredado en el códigoHaz grep; empareja cada uno con una regla :focus-visible
Estilo de foco personalizado≥2px, contraste alto contra el fondo, outline-offset: 2px
Inputs de textoMantén un indicador visible también en :focus — los navegadores lo muestran ahí incluso con puntero, por diseño
Navegadores muy viejosFallback con @supports not selector(:focus-visible) que estilice :focus

Trucos de power user

Recursos

Read this article in English

¿Construyendo una funcionalidad con AI? Yeda AI diseña, audita y entrega sistemas LLM de producción.

Habla con nosotros · Lee el blog