Input Color Feedback — README en npm Input Color Feedback — todo el código CSS Input Color Feedback — licencia MIT

Resumen

Input Color Feedback es un pequeño paquete de código abierto que escribí y publiqué en npm. Hace una sola cosa, y la hace bien: consigue que los inputs de formulario se sientan vivos. En cuanto un campo recibe el foco, brilla; y a medida que el usuario escribe, el borde cambia de color para decirle —sin una sola palabra de texto— si lo que ha introducido ya es válido o no.

Empezó como un fragmento que reescribía en cada formulario que construía. En lugar de copiarlo y pegarlo para siempre, lo convertí en una única hoja de estilos, lo documenté, le puse una licencia MIT y lo publiqué en npm para que cualquiera (yo incluido en el futuro) pueda añadirlo con un solo import.

La idea: un semáforo para los formularios

Todo se apoya en un lenguaje visual que ya habla todo el mundo: el semáforo. Verde significa bien, ámbar significa todavía no, rojo significa que hay un problema. En el fondo el paquete no es más que eso: la validación nativa de formularios, mapeada sobre unos colores que nadie tiene que aprender.

Para quien desarrolla es un pequeño estándar que se puede compartir — lo sueltas y todos los formularios de un proyecto (o de varios) hablan el mismo dialecto, en lugar de que cada uno reinvente su propio estilo de validación. Para quien lo usa es una forma coherente y sin palabras de leer el estado del campo que está rellenando. Ese era todo el objetivo aquí: coger un patrón que reescribía una y otra vez y compartir la parte que de verdad creo que ayuda a ambas partes.

Cómo funciona

Cada <input> transiciona su color de borde y su resplandor (box-shadow) según su estado de foco y validación. Hay seis estados, y cada uno le dice algo distinto al usuario:

  • Sin foco y vacío (el estado por defecto): un borde gris neutro, sin resplandor — el punto de partida sereno antes de que se haya tocado el campo.
  • Enfocado y vacío (con el placeholder aún visible): el borde brilla en azul: «estás aquí, adelante».
  • Enfocado pero inválido: el borde brilla en ámbar: «sigue, aún no está del todo».
  • Enfocado y válido: el borde brilla en verde: «eso funciona».
  • Sin foco e inválido: el borde se vuelve rojo sólido, sin resplandor — un marcador de error sereno una vez que has pasado de largo.
  • Sin foco y válido: el borde se queda verde, sin resplandor: confirmado en silencio.

El resplandor solo aparece en el campo enfocado, así que un formulario largo nunca se ilumina como un árbol de Navidad — tu vista se dirige exactamente al input en el que estás trabajando.

CSS puro, cero JavaScript

Toda la librería es una hoja de estilos corta y ni una sola línea de JavaScript. Toda la lógica vive en selectores CSS modernos que el navegador ya evalúa gratis: :focus, :placeholder-shown, :valid/:invalid y los dirigidos por el usuario :user-valid/:user-invalid — estos dos últimos son los que evitan que la página le grite «inválido» a un campo vacío que el usuario ni siquiera ha alcanzado todavía.

Como no hay script, no hay nada que inicializar, nada que empaquetar, ningún coste en tiempo de ejecución y nada que pueda romper el comportamiento existente de un formulario. Las transiciones de border-color y box-shadow se suavizan a lo largo de 0,3 s para que cada cambio de estado se sienta fluido en lugar de brusco.

Personalizable por diseño

Cada color es una propiedad personalizada de CSS declarada en :root, así que personalizar el tema es cuestión de sobrescribir un puñado de variables — sin Sass, sin paso de build y sin hacer un fork:

  • --default-color — el borde en reposo.
  • --focus-color — el resplandor azul del foco.
  • --valid-color — el estado verde de «válido».
  • --warning-color — el estado ámbar de «enfocado pero inválido».
  • --invalid-color — el estado rojo de «dejado inválido».
  • --shadow-strength — la intensidad del resplandor, mezclada en la sombra con color-mix().

Apunta esas variables a la paleta de tu marca y el feedback hereda tu lenguaje de diseño de forma automática.

Instalación y uso

Se instala con npm install input-color-feedback (o yarn add input-color-feedback) y luego importas la hoja de estilos — bien desde CSS con @import "input-color-feedback/styles.css"; o, con un bundler como Vite o Webpack, desde JavaScript con import 'input-color-feedback/styles.css';.

Esa es toda la configuración. No hay componentes que cablear ni clases que añadir — el estilo se apoya en la validación nativa de HTML, de modo que se activa en cuanto un input tiene un placeholder y una regla de validación como required, pattern o minlength. Los inputs sin eso no reaccionan, y es a propósito.

Claro y oscuro, de fábrica

La paleta por defecto está afinada para interfaces oscuras — como este sitio, y como Biglo, la aplicación en la que nació. Desde la v2.1.0 ya no se queda ahí: sobre un fondo claro, los dos colores que de otro modo no superarían el umbral de contraste de las WCAG — el verde de «válido» y el ámbar de «enfocado pero inválido» — se cambian automáticamente mediante prefers-color-scheme, oscureciendo el verde y virando el ámbar hacia el naranja para que ambos superen el 3:1 sobre blanco. Sin configurar nada.

Y como cada color sigue siendo una variable CSS, puedes re-tematizarlo para cualquier diseño — que es exactamente lo que hice en el sitio de Abogada de la Tierra: limité las variables de la librería al formulario de contacto, mantuve el color de borde en reposo de la propia página y ajusté la paleta para que se asiente cómodamente sobre un fondo crema.

Limitaciones y qué viene después

Prefiero ser claro sobre dónde se queda corto:

  • Necesita campos con restricciones. Como se apoya en la validación nativa, un input solo reacciona si realmente tiene una regla — un placeholder más algo como required, pattern o minlength. Un input sin restricciones es siempre :valid, así que se quedaría verde desde el primer instante.
  • Pero puedes sortearlo. En Abogada de la Tierra combiné el paquete con un formulario novalidate y un pequeño validador en JS que activa una clase .is-invalid para los errores al enviar, además de un modificador --optional para que los campos opcionales vacíos se queden neutros en lugar de ponerse verdes. El CSS aporta la sensación en vivo; unas pocas líneas de JS cubren los casos que la validación nativa no sabe expresar.
  • El color por sí solo no es del todo accesible. El tono por sí mismo puede fallarle a personas con daltonismo, que quizá no distingan el verde del ámbar o del rojo. Esto empezó como mi implementación personal para Biglo, y lo compartí porque creo que ayuda — no porque sea la solución definitiva. Ya estoy buscando formas de mejorarlo: acompañar el color con iconos, texto o estado ARIA para que el significado nunca dependa únicamente del color.

Estado

Publicado y disponible en npm como input-color-feedback, con el código en GitHub bajo licencia MIT. Actualmente va por la versión 2.1.0 — pequeño, estable y de uso libre para cualquiera.