Cuando trabajas con formularios, botones, enlaces o cualquier elemento interactivo de una página web, conocer las diferencias entre :focus y :focus-visible te permite mejorar tanto el diseño como la accesibilidad de tu sitio.
Aunque ambos selectores están relacionados con el foco de los elementos HTML, no se comportan exactamente de la misma manera y elegir correctamente entre ellos puede evitar bordes molestos sin perjudicar a los usuarios que navegan mediante teclado.
En este tutorial vas a descubrir qué hace :focus, cómo funciona :focus-visible, cuándo utilizar cada uno y cómo combinarlos correctamente mediante ejemplos sencillos de CSS.
🎯 ¿Qué significa que un elemento tenga el foco?
Un elemento tiene el foco cuando está preparado para recibir directamente una acción del usuario mediante el teclado u otro método de entrada.
Por ejemplo, cuando pulsas la tecla Tab y vas recorriendo enlaces, botones y campos de un formulario, el navegador va trasladando el foco entre los diferentes elementos interactivos.
El elemento seleccionado suele mostrar algún tipo de contorno, borde o indicador visual para que puedas saber rápidamente dónde te encuentras dentro de la página.
Este comportamiento resulta especialmente importante para personas que navegan utilizando exclusivamente el teclado y no dependen del ratón para interactuar con una web.
Puedes consultar más detalles sobre el funcionamiento del foco en la documentación de MDN sobre accesibilidad del teclado.
🔵 ¿Qué es :focus en CSS?
La pseudoclase :focus se aplica cuando un elemento recibe el foco, independientemente de la forma utilizada para llegar hasta él.
Esto significa que puede activarse tanto cuando haces clic con el ratón como cuando navegas mediante la tecla Tab.
Un ejemplo muy básico sería el siguiente:
button:focus {
outline: 3px solid #2271b1;
}
Con este código, el botón mostrará un contorno cuando reciba el foco, ya sea mediante teclado o mediante determinadas interacciones realizadas con otros dispositivos.
También puedes utilizarlo en campos de formulario para modificar su apariencia cuando el usuario comienza a interactuar con ellos.
input:focus {
border-color: #2271b1;
outline: none;
}
Este recurso es habitual para destacar el campo que se encuentra activo dentro de formularios relativamente largos.
Puedes ampliar información técnica sobre esta pseudoclase consultando la documentación de :focus en MDN.
🟢 ¿Qué es :focus-visible?
La pseudoclase :focus-visible también detecta cuándo un elemento recibe el foco, pero añade una diferencia fundamental respecto a :focus.
El navegador utiliza diferentes criterios para decidir si debe mostrar el indicador visual del foco, teniendo en cuenta principalmente la forma en la que el usuario está interactuando con la página.
Cuando navegas utilizando el teclado, normalmente el navegador considera necesario mostrar claramente el foco y aplica :focus-visible.
Cuando utilizas el ratón, en muchas situaciones el navegador determina que ese indicador adicional no es necesario y :focus-visible no se activa visualmente de la misma manera.
Por ejemplo:
button:focus-visible {
outline: 3px solid #2271b1;
outline-offset: 3px;
}
Con esta regla puedes mostrar un contorno muy claro cuando una persona navega mediante teclado sin añadir necesariamente ese mismo efecto cada vez que pulsa un botón con el ratón.
Puedes consultar la especificación práctica de esta pseudoclase en la documentación de :focus-visible en MDN.
⚔️ Diferencia principal entre :focus y :focus-visible
La principal diferencia es que :focus detecta directamente el estado de foco, mientras que :focus-visible permite al navegador determinar cuándo existe una necesidad visual de mostrar ese foco.
Dicho de una forma más sencilla, :focus responde a si existe foco y :focus-visible responde además a si ese foco debería mostrarse claramente al usuario.
Esta diferencia aparentemente pequeña puede mejorar considerablemente la experiencia de navegación de una página web.
📊 Tabla resumen de :focus y :focus-visible
| Característica | :focus | :focus-visible |
|---|---|---|
| Detecta el foco | Sí | Sí |
| Pensado para accesibilidad | Sí | Especialmente útil |
| Puede activarse tras usar el ratón | Sí | Depende del contexto |
| Muy útil para navegación con teclado | Sí | Sí |
| Permite reducir indicadores innecesarios | No directamente | Sí |
| Compatible con CSS moderno | Sí | Sí |
| Recomendable para indicadores visuales de teclado | Puede utilizarse | Muy recomendable |
💻 Ejemplo práctico con un botón
Imagina que tienes un botón al que quieres añadir un contorno únicamente cuando resulte necesario para facilitar la navegación mediante teclado.
Tu HTML podría ser simplemente:
<button>Enviar formulario</button>
Una implementación sencilla con :focus-visible sería:
button:focus-visible {
outline: 3px solid #000;
outline-offset: 4px;
}
Al navegar por la página mediante Tab, podrás identificar claramente cuándo el botón recibe el foco.
Esta técnica evita llenar el diseño de contornos innecesarios durante determinadas interacciones con el ratón sin eliminar una ayuda fundamental para la navegación mediante teclado.
⚠️ El error de utilizar outline: none
Uno de los errores CSS más frecuentes consiste en eliminar completamente el contorno del foco mediante outline: none.
button:focus {
outline: none;
}
Aunque esta regla puede hacer que determinados botones parezcan visualmente más limpios, también puede provocar un problema importante de accesibilidad.
Si eliminas el indicador sin sustituirlo por otro estilo, una persona que navegue mediante teclado podría no saber qué elemento se encuentra seleccionado.
Si necesitas eliminar el contorno predeterminado del navegador, deberías añadir inmediatamente una alternativa visual claramente reconocible.
button:focus-visible {
outline: 3px solid #2271b1;
outline-offset: 3px;
}
De esta manera mantienes un diseño personalizado sin sacrificar la visibilidad del foco.
🛠️ Cómo utilizar correctamente :focus-visible
Puedes implementar :focus-visible siguiendo unos pasos muy sencillos que mantendrán tu interfaz limpia y accesible.
- 🔎 Identifica los elementos interactivos de tu web, como enlaces, botones, campos, selectores y controles personalizados.
- ⌨️ Recorre la página utilizando únicamente Tab y Shift + Tab para comprobar que puedes acceder a todos los elementos importantes.
- 🎨 Añade un estilo suficientemente visible con
:focus-visiblepara que puedas localizar fácilmente el elemento seleccionado. - 📏 Utiliza
outline-offsetcuando necesites separar ligeramente el indicador del borde original del elemento. - 🚫 Evita eliminar completamente el foco mediante
outline: nonesi no vas a introducir una alternativa equivalente. - 🧪 Prueba tu página con ratón y teclado para comprobar que el comportamiento resulta cómodo en ambos sistemas de navegación.
- 📱 Comprueba diferentes navegadores y dispositivos cuando desarrolles componentes interactivos especialmente complejos.
🎨 Combinar :focus y :focus-visible
No tienes necesariamente que elegir entre una pseudoclase y otra, ya que en determinados diseños puedes combinar :focus y :focus-visible para controlar diferentes propiedades.
Por ejemplo:
input:focus {
border-color: #2271b1;
}
input:focus-visible {
outline: 3px solid #2271b1;
outline-offset: 2px;
}
Con este código, el campo puede cambiar el color del borde siempre que recibe el foco, mientras que el contorno adicional aparecerá cuando el navegador considere necesario mostrar claramente el indicador.
Esta combinación resulta especialmente interesante en formularios, interfaces administrativas y aplicaciones web donde existen numerosos controles interactivos.
🔗 ¿También funciona con enlaces?
Sí, puedes utilizar :focus-visible con enlaces exactamente igual que con botones y campos de formulario.
a:focus-visible {
outline: 2px dashed currentColor;
outline-offset: 4px;
}
Esto permite que los usuarios que recorren una página mediante teclado puedan identificar con rapidez qué enlace está seleccionado antes de abrirlo.
En páginas con muchos enlaces, menús o elementos de navegación, disponer de un indicador claro puede mejorar considerablemente la experiencia de usuario.
♿ :focus-visible y accesibilidad web
La visibilidad del foco forma parte de una correcta estrategia de accesibilidad web, ya que una interfaz no debería depender exclusivamente del ratón.
Las pautas de accesibilidad de W3C Web Accessibility Initiative explican la importancia de ofrecer interfaces utilizables mediante diferentes métodos de interacción.
Utilizar correctamente :focus-visible permite crear diseños modernos sin perjudicar a quienes dependen del teclado para navegar por Internet.
Además, un indicador de foco claro no beneficia exclusivamente a personas con determinadas discapacidades, ya que también puede resultar práctico para usuarios avanzados que prefieren desplazarse rápidamente mediante el teclado.
🧠 ¿Cuándo utilizar :focus?
Utiliza :focus cuando necesites modificar una propiedad de un elemento siempre que este se encuentre enfocado, independientemente del método empleado para interactuar con él.
Por ejemplo, puede ser apropiado para cambiar el borde de un input, activar una animación discreta o modificar el fondo de un control cuando está activo.
También resulta útil cuando el estado de foco tiene consecuencias funcionales que deberían aplicarse independientemente de si el usuario está utilizando teclado, ratón u otro dispositivo.
✨ ¿Cuándo utilizar :focus-visible?
Utiliza :focus-visible principalmente cuando quieras crear un indicador específicamente pensado para mostrar con claridad qué elemento está seleccionado durante la navegación.
Es especialmente apropiado para propiedades como outline, box-shadow, bordes destacados o cambios visuales fuertes destinados a señalar el elemento activo.
En muchos proyectos modernos, :focus-visible ofrece una forma más elegante de equilibrar diseño y accesibilidad.
🚀 Ejemplo recomendado para una web
Una configuración sencilla que puedes adaptar a muchos proyectos sería la siguiente:
a:focus-visible,
button:focus-visible,
input:focus-visible,
textarea:focus-visible,
select:focus-visible {
outline: 3px solid currentColor;
outline-offset: 3px;
}
Utilizar currentColor permite que el contorno herede el color actual del elemento, facilitando su integración dentro del diseño.
Puedes modificar el grosor, separación y estilo del outline dependiendo de la estética de tu página, pero debes procurar que el indicador continúe siendo claramente perceptible.
✅ Conclusión
Entender las diferencias entre :focus y :focus-visible te ayuda a crear interfaces más agradables sin descuidar a quienes utilizan métodos de navegación distintos al ratón.
Recuerda que :focus indica que un elemento tiene el foco, mientras que :focus-visible permite aplicar estilos cuando resulta especialmente importante mostrar visualmente ese estado.
En lugar de eliminar indiscriminadamente los contornos que incorpora el navegador, puedes utilizar :focus-visible para conseguir un resultado más limpio, moderno y accesible.
Si estás desarrollando botones, formularios, menús o cualquier otro componente interactivo, merece la pena revisar sus estados de foco porque pequeños detalles de CSS pueden marcar una gran diferencia en la experiencia de navegación.
