Complete Input
Every state a real text field has: a floating label, a focus halo, an error that waits for blur and forgives on input, and a check that draws itself
That doesn't look like an email address
Build my text input properly. Not a new effect, just every state a real field already needs. The label and the error message are listed at the end; use those exact values. For colours, use my site's existing focus colour; the specifics below describe behaviour, not a palette. Render only the field itself: one label, one input, and the message line beneath it. Do not add state names, captions, a legend, or any demo text around it. Structure: a real label element tied to the input with for and id, not a placeholder pretending to be one. The label starts inside the field at full size, and once the field gains focus or has content it floats up and shrinks. Animate only transform (translateY and scale, transform-origin left center), about 160ms with an ease-out curve like cubic-bezier(0.22, 1, 0.36, 1), so nothing reflows. A placeholder that disappears takes the question with it; a label that floats keeps it on screen. Reserve the message line's height beneath the field permanently, even while it is empty. The error fades and slides in over about 160ms, and because its slot was always there, nothing below the field ever jumps. Transitions: name the properties one by one, border-color 180ms and box-shadow 180ms. Never use transition: all. On focus: the border takes the focus colour and gains a soft halo, a box-shadow of 0 0 0 3px in the focus colour at roughly 14% opacity (color-mix(in srgb, the colour 14%, transparent) does this cleanly). The floated label takes the focus colour too. Inputs show their focus treatment on click as well as keyboard, and for form fields that is correct; do not suppress it. Validation timing is the craft: the field judges on blur and forgives on input. Show the error only when the user leaves the field with an invalid value, never while they are still typing their first attempt. Once an error is showing, re-check on every keystroke and clear it the moment the value turns valid. A field that complains mid-typing feels broken; one that keeps the error after the fix feels sulky. The error state: the border switches to a functional red like #D64545 with a matching light halo, the message appears in the reserved line in the same red at around 12px, the input gets aria-invalid="true", and aria-describedby points at the message so screen readers announce it. Play one small shake when the error first appears, translateX 0 to -4px to 4px to -2px to 0 over about 260ms, once, and never again on keystrokes. When the value turns valid, and the field is either left or has just recovered from an error, draw a small checkmark inside the field's right edge: an SVG path animating from 0 to full length over about 300ms in a functional green like #2E9E5B. The check is confirmation, not celebration, so no bounce. Under prefers-reduced-motion: the label snaps between its two positions, the shake is dropped, and the check appears without drawing. Every state must still read by colour and content alone. Make it mine: - Label the field "Email address". - When the value is invalid, show "That doesn't look like an email address" beneath the field. Build the component, not this demo of it. - Ambient motion that IS the component may loop: a drifting background, a marquee, a spinner while something is genuinely loading. - Do not add any timer, interval, loop or script that performs a person's action by itself. No auto-hover, no auto-click, no cycling through states, no pretend submitting, no replaying the interaction on a schedule. - Every state that answers a person waits for a real event from that person. - Placeholder copy and sample content are welcome. Simulated behaviour is not.