Introducción
En este tutorial práctico aprenderás a estilizar los campos de formularios en WordPress para que el indicador de foco sea visible, consistente y accesible. Un foco bien diseñado no solo mejora la estética, sino que es fundamental para la navegación por teclado, la usabilidad y el cumplimiento de las pautas de accesibilidad (WCAG). No elimines nunca el foco nativo sin ofrecer una alternativa igualmente visible.
Principios básicos y buenas prácticas
- Visibilidad: el usuario con teclado debe ver claramente qué elemento tiene el foco.
- Contraste: el color del indicador debe cumplir contraste suficiente frente al fondo (WCAG recomienda 3:1 para componentes no textuales objetivo mayor para texto importante).
- No ocultar outlines: evitar reglas como outline: none sin reemplazo accesible.
- :focus-visible: usar la pseudo-clase cuando sea posible para diferenciar entre foco por teclado y por puntero.
- Preferencias del usuario: respetar prefers-reduced-motion si hay animaciones en el foco.
- Compatibilidad con modos de alto contraste: comprobar forced-colors (Windows High Contrast) y asegurar que el indicador permanezca claro.
Qué elementos afectar
- Inputs de texto, email, password, textarea
- Botones (input[type=submit], button)
- Selects y opciones
- Checkboxes y radios (controles personalizados)
- Elementos interactivos generados por plugins (Contact Form 7, Gravity Forms, WPForms, etc.)
Ejemplo base de CSS accesible para foco
Este bloque CSS es un punto de partida que puedes incluir en tu tema o en la hoja de estilos del plugin. Usa variables para integrar con tu sistema de diseño.
:root {
--focus-color: #2563eb / azul accesible de ejemplo /
--focus-ring-color: rgba(37, 99, 235, 0.2)
--focus-outline-width: 3px
--focus-offset: 3px
--focus-border-radius: 6px
}
/ Base para campos de entrada y textarea /
input[type=text],
input[type=email],
input[type=password],
textarea,
select,
button {
outline: none / quitamos el outline nativo para controlarlo nosotros /
border-radius: 6px
transition: box-shadow 150ms ease, border-color 150ms ease
}
/ Indicador de foco accesible: usar box-shadow outline-offset visual /
:focus-visible {
/ Borde principal para compatibilidad visual /
box-shadow:
0 0 0 var(--focus-offset) var(--focus-ring-color),
0 0 0 calc(var(--focus-offset) var(--focus-outline-width)) var(--focus-color)
/ Asegura contraste con el fondo /
border-color: var(--focus-color)
}
/ Fallback para navegadores que no reconocen :focus-visible /
:focus {
box-shadow:
0 0 0 var(--focus-offset) var(--focus-ring-color),
0 0 0 calc(var(--focus-offset) var(--focus-outline-width)) var(--focus-color)
border-color: var(--focus-color)
}
/ Respetar preferencia de reducir movimiento /
@media (prefers-reduced-motion: reduce) {
:focus-visible,
:focus {
transition: none
}
}
/ Botones con foco más pronunciado /
button:focus-visible {
box-shadow:
0 0 0 4px rgba(37,99,235,0.15),
0 0 0 8px rgba(37,99,235,0.06)
}
/ Ejemplo para inputs con iconos (padding ajustado) /
.input-has-icon {
padding-left: 2.5rem / dejar espacio para el icono /
}
Estilizando checkboxes y radios personalizados
Los controles nativos de checkbox y radio tienen indicadores de foco inconsistentes entre navegadores. Aquí hay una estrategia: mantener el control nativo accesible pero oculto visualmente, y representar el estado con un elemento visual que reciba foco.
/ Contenedor accesible /
.field-checkbox {
display: inline-flex
align-items: center
gap: 0.5rem
}
/ Ocultar el control nativo manteniendo accesibilidad /
.field-checkbox input[type=checkbox],
.field-radio input[type=radio] {
position: absolute
opacity: 0
width: 1px
height: 1px
margin: -1px
clip: rect(0 0 0 0)
overflow: hidden
}
/ Visual personalizado que sí muestra foco /
.custom-control {
width: 1.1rem
height: 1.1rem
border-radius: 0.25rem
border: 2px solid #666
display: inline-block
position: relative
transition: box-shadow 120ms ease, border-color 120ms ease
}
/ Foco para el control visual /
.field-checkbox input[type=checkbox]:focus-visible .custom-control,
.field-radio input[type=radio]:focus-visible .custom-control {
box-shadow: 0 0 0 4px rgba(37, 99, 235, 0.15)
border-color: var(--focus-color)
}
/ Estado checked (simulación visual) /
.field-checkbox input[type=checkbox]:checked .custom-control {
background: var(--focus-color)
border-color: var(--focus-color)
}
Integración en WordPress: añadir el CSS correctamente
La forma recomendada para añadir estilos en WordPress es usar wp_enqueue_style desde functions.php del tema o un plugin. Evita imprimir estilos inline en plantillas compartidas sin control.
/ functions.php del tema /
function tema_enqueue_focus_styles() {
wp_enqueue_style(
tema-accesibilidad-foco,
get_stylesheet_directory_uri() . /assets/css/accesibilidad-foco.css,
array(),
1.0
)
}
add_action(wp_enqueue_scripts, tema_enqueue_focus_styles)
Si prefieres inyectar unas pocas reglas rápidas, usa wp_add_inline_style adjuntando a la hoja de estilos principal del tema.
Compatibilidad con plugins de formulario populares
Los plugins suelen añadir sus propias clases. A continuación ejemplos específicos para apuntar a ellos y garantizar foco consistente.
/ Contact Form 7 /
.wpcf7-form input:focus-visible,
.wpcf7-form textarea:focus-visible,
.wpcf7-form select:focus-visible {
box-shadow: 0 0 0 4px rgba(37,99,235,0.08), 0 0 0 7px #2563eb
border-color: #2563eb
}
/ Gravity Forms /
.gform_wrapper .gfield input:focus-visible,
.gform_wrapper .gfield textarea:focus-visible,
.gform_wrapper .gfield select:focus-visible {
box-shadow: 0 0 0 4px rgba(37,99,235,0.08)
border-color: #2563eb
}
/ WPForms /
.wpforms-form input:focus-visible,
.wpforms-form textarea:focus-visible,
.wpforms-form select:focus-visible {
outline: none
box-shadow: 0 0 0 6px rgba(37,99,235,0.12)
border-color: #2563eb
}
Mejorar la experiencia con JavaScript: detectar si el usuario usa teclado
Algunos proyectos usan la técnica de añadir una clase al body cuando el usuario navega con teclado (por ejemplo user-is-tabbing) y así estilizar únicamente en ese modo. Aquí un ejemplo ligero.
/ Añadir clase cuando el usuario tabula por teclado /
(function() {
function handleFirstTab(e) {
if (e.key === Tab) {
document.documentElement.classList.add(user-is-tabbing)
window.removeEventListener(keydown, handleFirstTab)
window.addEventListener(mousedown, handleMouseDownOnce)
}
}
function handleMouseDownOnce() {
document.documentElement.classList.remove(user-is-tabbing)
window.removeEventListener(mousedown, handleMouseDownOnce)
window.addEventListener(keydown, handleFirstTab)
}
window.addEventListener(keydown, handleFirstTab)
})()
Luego en CSS puedes hacer:
/ Estilos de foco solo cuando el usuario está usando teclado /
.user-is-tabbing :focus {
box-shadow: 0 0 0 4px rgba(37,99,235,0.12)
border-color: var(--focus-color)
}
Pruebas y auditoría
- Prueba exclusivamente con teclado: Tab, Shift Tab, Enter y Espacio.
- Verifica en lectores de pantalla (NVDA, VoiceOver, JAWS) que la navegación es clara y el foco corresponde al elemento anunciado.
- Prueba en modo High Contrast / forced-colors (Windows) y asegúrate de que se mantiene visibilidad.
- Comprueba contraste de colores utilizando herramientas como la comprobación de contraste (no incluyo enlaces por instrucción).
- Usa la consola de Chrome para forzar :focus y comprobar estilos sin usar el teclado.
Lista de verificación rápida antes de lanzar
- No eliminaste outlines sin proporcionar alternativa visible.
- El foco funciona en todos los campos y controles interactivos.
- Los colores del foco tienen suficiente contraste.
- Se respetan preferencias de movimiento reducido.
- Probado en plugins de formulario que uses en el sitio.
Valores recomendados
| Propiedad | Recomendación |
|---|---|
| Grosor del anillo | 2–4px visual (usar box-shadow con anillos múltiples) |
| Offset (separación) | 2–6px para evitar solapado con borde del control |
| Radio de borde | Consistente con el diseño del tema (4–8px típico) |
| Duración de transición | ≤ 150ms (y desactivar si prefers-reduced-motion) |
Notas finales
Un buen foco accesible es una combinación de diseño, contraste y comportamiento coherente. Adapta los ejemplos a tus variables de tema y prueba exhaustivamente en los formularios más usados del sitio. Implementa :focus-visible cuando sea posible y proporciona polyfills o técnicas complementarias para navegadores antiguos. Mantén los estilos centralizados y versionados para facilitar mantenimiento cuando actualices el tema o los plugins.
Leave a Reply