Addaw, ir a inicio Donar

Lección 6 de 10 · 12 min de lectura · Revisado el 26/10/2026

Estados visibles en CSS: contraste, foco, colores forzados y reflow

Hasta ahora nos hemos ocupado de lo que el formulario dice en el código. Esta lección se ocupa de lo que muestra en pantalla. Un campo bien etiquetado puede seguir siendo inaccesible si su borde casi no se ve, si el foco desaparece, si los errores solo cambian de color o si a 400 % de zoom las etiquetas se separan de sus campos. En el nivel 2 (cursos N2-C3 y N2-C4) vimos estas decisiones desde el diseño; aquí las implementamos en CSS sin romper nada y repasamos los criterios que las regulan: 1.4.11 Contraste no textual, 2.4.7 Foco visible, 1.4.4 Cambio de tamaño del texto, 1.4.10 Reajuste de los elementos, 1.4.12 Espaciado del texto, 2.5.8 Tamaño del objetivo (mínimo) y 1.4.13 Contenido con hover o foco.

Que un campo se vea como un campo

El criterio 1.4.11 (AA) exige una relación de contraste de al menos 3:1 con los colores adyacentes para la información visual necesaria para identificar un componente y sus estados. En un campo de texto, lo que suele permitir identificarlo es el borde. Si ese borde es gris claro sobre fondo blanco, para muchas personas con baja visión el formulario es una página con etiquetas flotando sobre nada.

Ejemplo

Incorrecto: un borde #CCCCCC sobre blanco tiene una relación de 1,6:1, y un campo identificado solo por un fondo #F5F5F5 sobre blanco se queda en 1,1:1.

input { border: 1px solid #ccc; }
.campo-plano { border: 0; background: #f5f5f5; }

Correcto: #767676 sobre blanco da 4,5:1, de sobra para el 3:1 exigido. Un borde de 2 píxeles, además, se distingue mejor.

input, select, textarea {
  border: 2px solid #767676;
  border-radius: 4px;
}

Lo mismo vale para el contorno de las casillas de verificación y de los botones de opción personalizados, y para el indicador que muestra que están marcados. Los componentes deshabilitados están exentos del requisito de contraste, pero eso no es una invitación a hacerlos invisibles: la persona tiene que saber que el campo existe aunque no pueda usarlo.

Estados: foco, error, marcado

Cada estado debe poder percibirse sin depender solo del color (1.4.1 Uso del color) y con contraste suficiente. La tabla resume cómo resolverlo en CSS.

EstadoQué exigirCómo hacerlo
FocoIndicador visible siempre que se use el teclado (2.4.7):focus-visible con outline de 2 px o más y outline-offset
ErrorTexto del error y algo más que el color en el campoSelector [aria-invalid="true"]: borde más grueso, icono y mensaje en texto
MarcadoUna forma (tic, punto) además del color de rellenoaccent-color o un dibujo en :checked con contraste 3:1
DeshabilitadoDistinguible, aunque esté exento de contrasteOpacidad moderada y cursor; nunca ocultarlo

Un detalle que ahorra muchos fallos: engancha el estilo de error al atributo ARIA, no a una clase aparte. Así es imposible que el campo se vea rojo sin estar marcado como no válido para el lector, o al revés.

input:focus-visible,
select:focus-visible,
textarea:focus-visible {
  outline: 3px solid #1a4fa0;
  outline-offset: 2px;
}

input[aria-invalid="true"] {
  border: 3px solid #b00020;   /* 7,3:1 sobre blanco */
}

Error frecuente

El clásico input:focus { outline: none; } heredado de una hoja de estilos de reseteo, a veces compensado con un cambio sutil de color del borde. Quien navega con teclado pierde la pista del campo en el que está. Si el diseño quiere otro indicador, sustitúyelo, no lo quites. En formularios largos vigila también 2.4.11 Foco no oculto (mínimo): una barra fija inferior («Total: 45 € Continuar») o un aviso de cookies pueden tapar por completo el campo enfocado. Reserva espacio con scroll-padding-bottom en el contenedor que se desplaza. El curso N3-C3 trata el foco en profundidad.

Modo de colores forzados

Muchas personas con baja visión o sensibilidad a la luz usan los temas de contraste de Windows. En ese modo, el navegador sustituye tus colores por los del sistema y aplica la consulta @media (forced-colors: active). Dos efectos rompen formularios con frecuencia:

  • Las sombras (box-shadow) se eliminan. Un anillo de foco hecho solo con sombra desaparece por completo.
  • Los fondos se sustituyen. Una casilla personalizada que muestra el estado «marcado» solo con un fondo de color deja de distinguirse de una vacía.

La solución es mantener siempre un outline o un borde, aunque sea transparente en el modo normal: en colores forzados el sistema le da color y vuelve a verse.

.boton:focus-visible {
  box-shadow: 0 0 0 4px #1a4fa0;
  outline: 2px solid transparent; /* visible en colores forzados */
}

@media (forced-colors: active) {
  .casilla-propia:checked::after {
    forced-color-adjust: none;   /* respeta este fondo… */
    background: CanvasText;      /* …con un color del tema del sistema */
  }
}

Tamaño, zoom y reflow

Los formularios son especialmente frágiles cuando se amplía el texto o se estrecha la ventana:

  • 1.4.4 (AA): el texto debe poder ampliarse al 200 % sin perder contenido. Un input con height: 32px fijo corta el texto al ampliarlo. Usa padding y min-height en rem, y deja que la altura crezca.
  • 1.4.10 Reajuste de los elementos (AA): a 320 píxeles CSS de ancho (equivalente a 1280 píxeles con zoom al 400 %) no debe hacer falta desplazarse en horizontal. La maquetación con etiquetas a la izquierda y campos a la derecha suele romperse: con zoom, la etiqueta queda a un lado de la pantalla y el campo fuera de la vista. Coloca las etiquetas encima de los campos y usa max-width: 100% en los controles.
  • 1.4.12 Espaciado del texto (AA): si la persona aumenta interlineado y espaciado, las etiquetas y los mensajes de error no deben cortarse. Evita alturas fijas y overflow: hidden en esos contenedores.
  • 2.5.8 Tamaño del objetivo (mínimo) (AA): los objetivos deben medir al menos 24 × 24 píxeles CSS o tener espacio suficiente alrededor. Una casilla nativa sin modificar queda exenta porque su tamaño lo decide el navegador; si la redibujas a 16 píxeles, la exención se pierde. En cualquier caso, la etiqueta asociada amplía el área en la que se puede pulsar.

Un consejo de diseño que también es de accesibilidad: el ancho del campo sugiere la longitud esperada. Un campo de código postal tan ancho como el de la dirección no ayuda a nadie; uno de 6 caracteres de ancho, sí.

Ayudas emergentes e instrucciones sensoriales

El icono de información junto a un campo que muestra una burbuja al pasar el ratón está sujeto a 1.4.13 (AA): la burbuja debe poder cerrarse sin mover el puntero (normalmente con Escape), debe poder recorrerse con el puntero sin que desaparezca y debe permanecer hasta que la persona la cierre o retire el puntero o el foco. Además, el icono debe ser un botón alcanzable con teclado. Siempre que quepa, es mejor mostrar la ayuda como texto visible asociado con aria-describedby.

Y cuidado con las instrucciones que dependen de la forma, el color o la posición, que incumplen 1.3.3 Características sensoriales (A) cuando son la única referencia: «Los campos en rojo son obligatorios», «Pulsa el botón verde», «Rellena los datos de la columna derecha».

Pruébalo tú

Abre un formulario en Chrome con la ventana a 1280 píxeles de ancho y pulsa Ctrl++ hasta llegar al 400 %. ¿Ves cada etiqueta junto a su campo sin desplazarte en horizontal? Después, en las herramientas para desarrolladores, abre el panel Rendering y emula forced-colors: active: recorre el formulario con Tab y comprueba que el foco y las casillas marcadas siguen viéndose.

Resumen

  • El borde o el indicador que identifica un campo y sus estados necesita contraste de 3:1 (1.4.11).
  • Nunca elimines el outline sin sustituirlo; usa :focus-visible y evita que barras fijas tapen el campo enfocado (2.4.11).
  • Engancha el estilo de error a [aria-invalid="true"] y añade texto e icono, no solo color.
  • En colores forzados desaparecen sombras y fondos: mantén siempre un borde u outline.
  • Etiquetas encima, alturas flexibles en rem y objetivos de 24 × 24 px mínimo para soportar zoom, reflow y uso táctil.

Comprueba lo que has aprendido

Esta lección se puede leer libremente. Para hacer su test de 3 preguntas, los ejercicios prácticos con páginas reales, guardar tu avance y optar al examen y al certificado, matricúlate en el curso.