Input Color Feedback
A tiny CSS utility I authored and published on npm. Drop it into any project and every form input starts giving live colour and glow feedback as the user types — blue while focused, green when valid, amber when not. No JavaScript, no dependencies, no markup changes.
Overview
Input Color Feedback is a small open-source package I wrote and published on npm. It does one thing well: it makes form inputs feel alive. The moment a field is focused it glows; as the user types, the border shifts colour to tell them — without a word of copy — whether what they've entered is valid yet.
It started as a snippet I kept rewriting on every form I built. Rather than copy-paste it forever, I distilled it into a single stylesheet, documented it, gave it an MIT licence and shipped it to npm so anyone (including future me) can add it with one import.
The idea: a traffic light for forms
The whole thing leans on a visual language everyone already speaks — traffic lights. Green means good, amber means not yet, red means there's a problem. That's all the package really is: native form validation, mapped onto colours nobody has to learn.
For developers it's a small, shareable standard — drop it in and every form across a project (or across projects) speaks the same dialect, instead of everyone reinventing their own validation styling. For users it's a consistent, wordless way to read the status of the field they're filling in. That was the entire goal here: take a pattern I kept rebuilding and share the part I think genuinely helps both sides.
How it works
Every <input> transitions its border colour and
glow (box-shadow) according to its focus and validation state. There are six
states, and each one tells the user something different:
- Unfocused and empty (the resting default) — a neutral grey border, no glow: the calm starting point before the field has been touched.
- Focused and empty (placeholder still showing) — the border glows blue: "you're here, go ahead".
- Focused but invalid — the border glows amber: "keep going, not quite right yet".
- Focused and valid — the border glows green: "that works".
- Unfocused and invalid — the border turns solid red, no glow: a calm error marker once you've moved on.
- Unfocused and valid — the border stays green, no glow: quietly confirmed.
The glow only ever appears on the focused field, so a long form never lights up like a Christmas tree — your eye is drawn to exactly the input you're working on.
Pure CSS, zero JavaScript
The whole library is one short stylesheet and not a single line of JavaScript. All the logic lives in
modern CSS selectors that the browser already evaluates for free:
:focus, :placeholder-shown, :valid/:invalid and
the user-driven :user-valid/:user-invalid — the last two are what keep the
page from yelling "invalid" at an empty field the user hasn't even reached yet.
Because there's no script, there's nothing to initialise, nothing to bundle, no runtime cost and
nothing that can break a form's existing behaviour. The transitions on border-color and
box-shadow are eased over 0.3s so every state change feels smooth rather than abrupt.
Themeable by design
Every colour is a CSS custom property declared on :root, so theming is a matter of
overriding a handful of variables — no Sass, no build step, no forking:
--default-color— the resting border.--focus-color— the blue focus glow.--valid-color— the green "valid" state.--warning-color— the amber "focused but invalid" state.--invalid-color— the red "left invalid" state.--shadow-strength— how intense the glow is, mixed into the shadow withcolor-mix().
Point those at your brand palette and the feedback inherits your design language automatically.
Installation & usage
Install it with npm install input-color-feedback (or yarn add input-color-feedback),
then pull in the stylesheet — either from CSS with
@import "input-color-feedback/styles.css"; or, with a bundler like Vite or Webpack, from
JavaScript with import 'input-color-feedback/styles.css';.
That's the entire setup. No components to wire up and no classes to add — the styling keys off native
HTML validation, so it activates as soon as an input has a placeholder and a validation
rule such as required, pattern or minlength. Inputs without
those won't react, which is by design.
Light and dark, out of the box
The default palette is tuned for dark interfaces — like this site, and like
Biglo, the app it was born in. As of v2.1.0 it no longer stops
there: on a light background the two colours that wouldn't otherwise meet the WCAG contrast
threshold — the valid green and the focused-but-invalid amber — are swapped automatically via
prefers-color-scheme, the green darkening and the amber shifting to orange so both
clear 3:1 on white. No configuration required.
And because every colour is still a CSS variable, you can re-theme it for any design — which is exactly what I did on the Abogada de la Tierra site: I scoped the library's variables to the contact form, kept the page's own resting border colour, and adjusted the palette so it sits comfortably on a cream background.
Limitations & what's next
I'd rather be upfront about where it stops short:
-
It needs constrained fields. Because it keys off native validation, an input only
reacts if it actually has a rule — a
placeholderplus something likerequired,patternorminlength. An unconstrained input is always:valid, so it would sit green from the very first paint. -
But you can work around it. On
Abogada de la Tierra I paired the package with a
novalidateform and a small JS validator that toggles an.is-invalidclass for submit-time errors, plus an--optionalmodifier so empty optional fields stay neutral instead of going green. The CSS handles the live feel; a few lines of JS handle the cases native validation can't express. - Colour alone isn't fully accessible. Hue on its own can fail colour-blind users, who may not separate green from amber or red. This started as my personal implementation for Biglo, and I shared it because I think it helps — not because it's the final word. I'm already looking at ways to improve it: pairing the colour with icons, text or ARIA state so the meaning never rests on hue alone.
Status
Published and live on npm as input-color-feedback, with the source on GitHub under an MIT licence. It's currently on version 2.1.0 — small, stable and free for anyone to use.