Introducción
La visibilidad del foco (focus) es una pieza clave de la accesibilidad: sin un indicador de foco claro, las personas que navegan con teclado (o con tecnologías asistivas) no pueden saber en qué elemento están. En WordPress, muchos temas colocan estilos por defecto que eliminan o suavizan demasiado el foco. Este artículo explica por qué el contraste del foco importa, qué exige WCAG, patrones CSS seguros y ejemplos concretos listos para integrar en tu tema o mediante el personalizador.
Por qué aumentar el contraste del foco importa
Un indicador de foco claro permite a usuarios mediante teclado, lectores de pantalla y otros dispositivos percibir la posición activa. WCAG 2.1 incluye requisitos relevantes:
- 2.4.7 Focus Visible (Nivel AA): todos los componentes interactivos deben mostrar un indicador de foco visible.
- 1.4.11 Non-text Contrast (Nivel AA): los componentes de la interfaz y sus indicaciones visuales (como el anillo de foco) deben presentar una relación de contraste de al menos 3:1 con los colores circundantes.
Consecuencia práctica: no basta con un borde fino y claro la combinación color/grosor debe ser perceptible y cumplir 3:1 frente al área contigua.
Buenas prácticas generales
- No elimines el outline por defecto sin reemplazarlo por otra solución claramente visible.
- Usa :focus-visible para mantener el foco visible para usuarios de teclado y evitar anillos molestos al hacer clic con ratón (con fallback para navegadores antiguos).
- Prefiere contornos opacos o sombras sólidas para facilitar el cálculo del contraste las sombras con alfa pueden reducir la efectividad del contraste.
- Asegúrate de que el grosor del anillo sea suficiente (por ejemplo 3px o más en contornos) para que sea perceptible en pantallas con baja resolución.
- Prueba con teclado, lector de pantalla y herramientas automáticas (axe, Lighthouse, WAVE) y con usuarios reales si es posible.
Patrones CSS recomendados
Abajo tienes patrones aplicables a enlaces, botones, inputs y elementos personalizados.
Indicador simple usando outline (fácil y accesible)
/ Indicador genérico para enlaces, botones y controles /
:focus-visible {
outline: 3px solid #0046d6 / color con alto contraste /
outline-offset: 3px
}
/ Fallback para navegadores sin :focus-visible /
:focus:not(:focus-visible) {
outline: none
box-shadow: none
}
Explicación: outline con offset es robusto y no afecta el tamaño del elemento. El color debe contrastar al menos 3:1 frente al fondo inmediato.
Anillo con box-shadow (más personalizable y moderno)
button:focus-visible,
a:focus-visible,
input:focus-visible,
textarea:focus-visible {
outline: none
box-shadow: 0 0 0 4px rgba(0,70,214,1) / anillo sólido /
border-radius: 6px / opcional: acorde al control /
}
Usar un color totalmente opaco (alfa = 1) facilita comprobar contraste. Si usas rgba semi-transparente, asegúrate de que el resultado sobre el background alcance 3:1.
Indicador para enlaces subrayados o minimalistas
a {
text-decoration: none
color: #0066cc
}
a:focus-visible {
text-decoration: underline
outline: 3px solid #ffa500 / color contrastante /
outline-offset: 2px
}
Si tu diseño elimina el subrayado por defecto, agrega otro indicador visual al recibir foco.
Skip link (enlaces de saltar al contenido)
/ Skip-to-content /
.skip-link {
position: absolute
left: -9999px
top: auto
width: auto
height: auto
background: #111
color: #fff
padding: 8px 12px
z-index: 9999
}
.skip-link:focus,
.skip-link:active {
left: 10px
top: 10px
}
Inputs y controles de formularios
input[type=text]:focus-visible,
select:focus-visible,
textarea:focus-visible {
outline: none
box-shadow: 0 0 0 3px #0046d6
border-color: #0046d6
}
Elementos no focusables que reciben tabindex (por ejemplo, tarjetas con tabindex)
.card[tabindex]:focus-visible {
box-shadow: 0 0 0 4px #ffbf00
transform: translateY(-2px) / opcional y sutil /
}
Si añades transformaciones, respeta preferencia de reducción de movimiento (prefers-reduced-motion).
Manejo de :focus-visible y polyfill
:focus-visible es ideal porque muestra el indicador sólo cuando procede (generalmente teclado). Para compatibilidad puedes usar la polyfill oficial https://github.com/WICG/focus-visible. Ejemplo de uso con clase JS fallback .focus-visible:
/ Si usas focus-visible polyfill que añade la clase .focus-visible /
:focus:not(.focus-visible) {
outline: none
box-shadow: none
}
Consideraciones para contrastes y colores
- La relación mínima requerida por 1.4.11 es 3:1 entre el indicador y los colores adyacentes. Usa herramientas como Colour Contrast Analyser para verificar.
- Evita anillos muy finos (1px) en fondos complejos: aumenta a 3-4px cuando el fondo es variable.
- Para temas oscuros, emplea anillos claros y opacos para temas claros, usa anillos oscuros con suficiente grosor.
- Si tu indicador es una sombra semitransparente, calcula el color resultante sobre el fondo para confirmar 3:1.
Compatibilidad con modos de alto contraste del sistema
Windows y browsers modernos soportan la media query forced-colors. Puedes aprovecharla para dejar que el sistema use sus colores nativos o reforzar el foco:
@media (forced-colors: active) {
:focus {
outline: 3px solid Highlight
outline-offset: 2px
box-shadow: none
}
}
Integración en WordPress
A continuación tienes varias formas de añadir los estilos a un sitio WordPress.
1) Añadir CSS en el Personalizador (fácil)
Ve a Apariencia → Personalizar → CSS adicional y pega tus reglas CSS. Es la forma más rápida para probar.
2) Añadir un archivo CSS en child theme y encolar
Crea un archivo focus-accessibility.css en tu child theme y encola desde functions.php:
lt?php
function tema_enqueue_focus_accessibility() {
wp_enqueue_style(
tema-focus-accessibility,
get_stylesheet_directory_uri() . /focus-accessibility.css,
array(),
1.0
)
}
add_action( wp_enqueue_scripts, tema_enqueue_focus_accessibility )
?gt
En focus-accessibility.css pega los estilos de ejemplo anteriores.
3) Usar theme.json (si tu tema lo soporta)
En themes basados en block theme puedes incluir estilos globales en theme.json, pero para reglas complejas :focus-visible sigue siendo más sencillo usar un archivo CSS encolar.
Consideraciones avanzadas
1) Focus dentro de modales y diálogos
- Asegúrate de que el primer elemento focusable en el modal tenga un indicador de foco claro.
- Respeta el trap de foco (focus trap) para que el usuario no pierda el foco fuera del modal.
2) Elementos SVG y canvas
Para elementos SVG con tabindex, aplica :focus-visible en el contenedor o en el svg mismo. En algunos casos es mejor añadir un rectángulo/outline dentro del SVG para control total.
3) Animaciones y motion
Si animas el anillo de foco, respeta prefers-reduced-motion y evita parpadeos que puedan causar problemas sensoriales.
Comprobaciones y pruebas
- Navega solo con teclado (Tab, Shift Tab, Enter) y observa el indicador en todos los elementos interactivos.
- Usa herramientas: Lighthouse (Chrome), axe (browser extension), WAVE.
- Verifica la relación de contraste del anillo contra el fondo (Colour Contrast Analyser, contrast-ratio.com).
- Prueba con modos de alto contraste del sistema y con lectores de pantalla básicos.
- Prueba en dispositivos móviles con teclado externo o mediante focus simulation en devtools.
Tabla rápida: patrón recomendado por componente
| Componente | Patrón recomendado | Grosor / Color |
|---|---|---|
| Enlaces | outline o box-shadow underline en foco | 3px, color con contraste ≥3:1 |
| Botones | box-shadow 3–4px o outline-offset | 3–4px, opaco |
| Inputs | border-color box-shadow | 3px anillo |
| Skip-link | posicionar fuera y mover a visible en foco | fondo sólido texto contrastado |
Ejemplos completos listos para copiar
Ejemplo completo y sencillo que puedes poner en tu archivo CSS del tema o en CSS adicional:
/ Focus accesible global /
:focus {
outline: none / evitamos outline predeterminado y reemplazamos por regla más accesible /
}
/ Preferimos focus-visible /
:focus-visible {
outline: 3px solid #0046d6
outline-offset: 3px
box-shadow: none
}
/ Alternativa con anillo /
button:focus-visible,
a:focus-visible,
input:focus-visible,
textarea:focus-visible {
outline: none
box-shadow: 0 0 0 4px #ffbf00 / anillo amarillo contrastado /
border-radius: 6px
}
/ Skip link /
.skip-link {
position: absolute
left: -9999px
top: auto
background: #000
color: #fff
padding: 8px 12px
z-index: 9999
}
.skip-link:focus,
.skip-link:active {
left: 10px
top: 10px
}
/ Fallback para navegadores antiguos: si no existe focus-visible, no quitar outline para evitar perder foco /
:focus:not(:focus-visible) {
outline: none
box-shadow: none
}
/ Respetar reduce motion /
@media (prefers-reduced-motion: reduce) {
{
transition: none !important
}
}
/ High contrast systems /
@media (forced-colors: active) {
:focus {
outline: 3px solid Highlight
outline-offset: 2px
box-shadow: none
}
}
Conclusión práctica
Mejorar el contraste del foco en WordPress requiere tres acciones simples: 1) no eliminar el foco, 2) aplicar un indicador visible y con contraste mínimo 3:1, y 3) probar con teclado y herramientas. Integra los fragmentos CSS en tu tema o mediante el personalizador, verifica contra WCAG y ajusta colores/grosor según tu paleta. Implementar estas mejoras aumenta la usabilidad y accesibilidad de tu sitio de forma inmediata.
Leave a Reply