Buenas prácticas
Enfoque visible: por qué outline: none rompe la accesibilidad con teclado
Si se elimina el outline CSS por estética, se hace el sitio inutilizable con el teclado. Esta práctica extendida vulnera dos criterios WCAG en juego: el enfoque visible (2.4.7) y el enfoque no oculto (2.4.11). Las soluciones modernas, como :focus-visible y outline-offset, permiten un indicador discreto, contrastado y conforme.

La respuesta corta
El indicador de foco (a menudo un contorno gris o azul) señala que un elemento de formulario, un enlace o un botón recibe la interacción mediante el teclado. Eliminar este contorno con *outline: none* sin reemplazarlo hace invisible la navegación por teclado: una discapacidad grave para cualquier usuario que no pueda utilizar el ratón. El criterio WCAG 2.4.7 lo exige; el 2.4.11 especifica que no debe estar oculto.
El foco no solo sirve para mostrar que un elemento está seleccionado. También permite entender dónde se encuentra uno en el recorrido de la página, qué acción se activará con la tecla *Intro* y qué campo recibirá el próximo ingreso de datos. Sin referencia visual, el usuario debe adivinar su posición o reiniciar la navegación desde el principio.
La corrección, por tanto, no consiste en conservar obligatoriamente el estilo nativo del navegador. Consiste en garantizar un indicador perceptible, coherente y con suficiente contraste en cada componente interactivo. Este indicador puede respetar la identidad gráfica del sitio, siempre que permanezca visible en todos los estados y sobre todos los fondos.
Por qué outline: none se convirtió en un hábito
El *outline* predeterminado de los navegadores es un rectángulo gris o azul bastante grueso, impuesto desde los años 1990 por seguridad de acceso. A partir de los años 2010, los diseñadores lo consideraron antiestético: «rompería» el diseño minimalista. Los resets de CSS (*Normalize*, *Reset* o los nativos de *Bootstrap*) comenzaron a ocultarlo, a menudo sin reemplazo: «outline: none» se propagó como patrón estándar en *frameworks* y talleres de desarrollo.
El problema es sistémico: esta supresión es casi automática, rara vez intencional. El estudio *Inclaria 2026* muestra que, entre los 55 sitios de comercio electrónico franceses analizados, la mayoría de las no conformidades críticas incluyen al menos una supresión de *outline* sin reemplazo. Es un síntoma: no hay pruebas con teclado ni revisión de accesibilidad en la fase inicial del diseño.
Otra causa frecuente es la confusión entre el *focus* activado por un clic y el activado por el teclado. Los equipos desean eliminar el anillo que aparece tras un clic del ratón y luego aplican *outline: none* a todos los estados *:focus*. Esta regla afecta entonces también a las personas que utilizan *Tab*, *Mayús + Tab* o una tecnología de asistencia. *:focus-visible* resuelve precisamente este problema al distinguir las modalidades de interacción.
¿Quién queda bloqueado?
Cuatro perfiles se ven directamente afectados.
- Los usuarios que solo utilizan teclado: discapacidad motora, temblores, parálisis o tecnología de asistencia (pedal, ratón adaptado). No ven nada al tabular en el formulario.
- Los usuarios que navegan con teclado por preferencia: desarrolladores, analistas de datos, *power users* que ganan 15 segundos por formulario, personas ciegas o con baja visión que navegan con un lector de pantalla (que suele basarse en el foco visual del navegador o en un anillo de lector).
- Los usuarios mayores o en situación de fatiga motora: la precisión con el ratón se vuelve difícil; el teclado es más fácil y rápido.
- Situaciones de discapacidad temporal: brazo roto, *trackpad* defectuoso, trabajar en un monitor táctil sin ratón.
El bloqueo puede ser total en un formulario largo. Una persona puede llegar hasta el botón de validación sin saber qué control está activo, activar involuntariamente un enlace secundario o modificar un campo ya completado. En una ventana modal, la ausencia de indicador también puede dar la impresión de que el teclado ha dejado de funcionar, cuando el foco sigue desplazándose por elementos invisibles o situados detrás de la ventana.
Los criterios WCAG en juego
Dos criterios plantean problemas:
| Critère | Exigencia | Impacto de outline: none |
|---|---|---|
| WCAG 2.4.7: Enfoque visible | Todo elemento de formulario o elemento interactivo que pueda recibir el enfoque DEBE tener un indicador de enfoque visible. | outline: none sin reemplazo hace que el indicador sea invisible: violación directa. |
| WCAG 2.4.11: Enfoque no oculto | El indicador de enfoque no debe ser ocultado por otros elementos de la página (por ejemplo, una barra fija, un menú superpuesto). | Un outline: none combinado con outline-offset: -2px (o negativo) oculta aún más la indicación. |
A nivel de conformidad legal, estos dos criterios son de nivel AA, obligatorios en Francia bajo la directiva europea (European Accessibility Act, aplicable a partir del 28 de junio de 2025 para los nuevos servicios, 28 de junio de 2030 para los servicios existentes).
La visibilidad debe verificarse en condiciones reales de uso, no solo en un componente aislado dentro de una biblioteca de diseño. Un anillo conforme sobre fondo blanco puede volverse imperceptible en un banner azul, ser cortado por overflow: hidden o desaparecer bajo un encabezado posicionado como fixed. La conformidad depende, por tanto, del renderizado final, de la posición del elemento y de su entorno visual.
La solución moderna: :focus-visible y outline-offset
Los navegadores modernos y las tecnologías de asistencia soportan :focus-visible (desde 2018, IE 11 no es compatible, pero requiere una estrategia degradada: .element:focus { outline: 2px solid #0066cc; } y luego .element:focus-visible { /* reglas refinadas */ }).
La regla a recordar: :focus-visible solo apunta al enfoque mediante teclado, no al enfoque con el ratón (en .element:focus-visible { … }). Esto permite mantener la interfaz limpia al hacer clic, al tiempo que se conserva la accesibilidad con el teclado.
Ejemplo 1: reemplazar el outline por defecto
a, button, input:focus-visible { outline: 2px solid #0066cc; outline-offset: 2px; }
Aquí, outline-offset: 2px crea un espacio entre el elemento y el anillo, lo que evita ocultar el contenido (criterio 2.4.11).
Para una cobertura homogénea, la misma lógica debe aplicarse a otros componentes interactivos: áreas de texto, listas desplegables, controles personalizados, elementos con tabindex y widgets JavaScript. Añadir una regla solo a los enlaces y botones suele dejar lagunas en el recorrido del teclado.
Ejemplo 2: outline gris con contraste, también para modo oscuro
a:focus-visible, button:focus-visible, input:focus-visible { outline: 3px solid #333; outline-offset: 4px; } @media (prefers-color-scheme: dark) { a:focus-visible, button:focus-visible, input:focus-visible { outline: 3px solid #fff; } }
Se respeta el contraste mínimo de 3:1 (enlace 1.4.11, tono de gris): #333 sobre blanco = 8,6:1 de contraste.
Ejemplo 3: box-shadow como indicador
¿Qué pasa si realmente quieres reemplazar el outline? box-shadow también funciona, pero no crea un desplazamiento como outline-offset:
a:focus-visible { outline: none; box-shadow: 0 0 0 3px #0066cc; }
Atención: box-shadow consume un poco más de GPU que outline y no se dibuja fuera de los contenedores con `overflow: hidden`. outline es más robusto.
Si outline: none sigue siendo necesario en una regla específica, su reemplazo debe definirse en el mismo bloque o en una regla inmediatamente identificable. Esta proximidad limita el riesgo de que una modificación futura en la cascada elimine el indicador alternativo. También es necesario probar los estados combinados, especialmente :hover, :active, :disabled y :focus-visible, para que un estilo más específico no sobrescriba accidentalmente el enfoque.
Cómo comprobar que el foco es visible
- Pulsar la tecla Tab en el teclado: cada elemento interactivo (enlace, botón, campo de entrada) debe tener un anillo visible alrededor.
- Abrir las DevTools del navegador (F12), pestaña «Accessibility» (Chrome, Edge) o «Inspector → Accessibility» (Firefox), y observar el indicador de foco al tabular.
- Usar un lector de pantalla (NVDA en Windows, VoiceOver en Mac/iOS): anuncia el elemento en foco; el foco visual debe coincidir al mismo tiempo.
La prueba debe cubrir toda la página en ambos sentidos, con Tab y luego Mayús + Tab. El orden de desplazamiento debe mantenerse lógico, el indicador no debe desaparecer nunca y ningún elemento debe atrapar el teclado. También hay que abrir menús, acordeones, ventanas modales y componentes dinámicos, ya que su comportamiento no siempre es visible en un simple recorrido por la página principal.
Por último, prueba con varios anchos de pantalla y niveles de zoom. Al 200 %, un encabezado fijo o un banner de consentimiento puede superponerse al elemento enfocado, aunque todo parezca correcto al 100 %. El foco debe permanecer al menos parcialmente visible cuando el contenido se reorganiza.
Detección de eliminaciones de outline
El escáner Inclaria prueba dos cosas: (1) la presencia de un indicador de foco visible en los elementos clave (formularios, botones, enlaces); (2) el desplazamiento de este indicador (sin ocultación bajo un menú fijo, por ejemplo). Una supresión de «outline: none» sin reemplazo se marca como no conforme con la WCAG 2.4.7.
El informe prioriza este defecto: aparece a menudo en cientos de elementos (CSS reset aplicado en todas partes) y tiene un impacto directo en la usabilidad.
Una detección automatizada permite identificar rápidamente las reglas CSS sospechosas y los componentes sin estilo de reemplazo. No obstante, debe complementarse con una prueba manual con teclado, ya que la visibilidad real depende del contraste, del contexto gráfico, del desplazamiento y de posibles elementos superpuestos.
Preguntas frecuentes
¿Debo mantener absolutamente el outline predeterminado del navegador?
No: puedes adaptarlo al diseño, pero debes reemplazarlo, nunca eliminarlo solo. outline: 2px solid #0066cc; outline-offset: 2px; es discreto, profesional y conforme.
¿Qué ocurre si mezclo :focus (ratón) y :focus-visible (teclado)?
Es la buena práctica moderna. :focus se aplica en ambos casos (ratón + teclado), :focus-visible solo al teclado. Puedes tener .elemento:focus { /* nada */ } y .elemento:focus-visible { outline: 2px solid #0066cc; }, lo que hace que el ratón sea discreto y el teclado accesible.
¿El contraste 3:1 del indicador se aplica también sobre imágenes?
Sí: el criterio 1.4.11 establece que el indicador de foco debe tener un contraste 3:1 respecto a todos los píxeles adyacentes. Si tu outline pasa sobre una foto en color, el color del outline debe mantener siempre 3:1 contra el fondo. Usar box-shadow oscuro u outline blanco/negro en todos los fondos es más seguro.
Mis usuarios nunca navegan con el teclado. ¿Puedo ignorar :focus-visible?
Es una violación legal a partir de junio de 2025 (EAA). También es una mala suposición: los evaluadores, los reguladores, las personas con discapacidad motriz y los usuarios avanzados lo harán. Que una fracción de tus usuarios no lo haga no es justificación.
¿Cómo se aplica la cascada entre :focus-visible y :focus en mi CSS reset?
Escribe: a { } luego a:focus { } (opcional: nada o sombra ligera) y después a:focus-visible { outline: 2px solid #0066cc; outline-offset: 2px; }. El navegador aplica :focus primero, luego :focus-visible si es teclado: :focus-visible prevalece.
¿Se puede usar border en lugar de outline para el indicador de foco?
Sí, pero border desplaza el elemento (box-sizing: border-box lo limita). outline no desplaza nada: es una ventaja. outline + outline-offset es el camino más seguro.
Definiciones relacionadas
Leer a continuación
Empiece con un escaneo gratuito
Obtenga su puntuación de accesibilidad, sus problemas prioritarios y la declaración que falta en segundos.
Escanear mi sitio