Success Checkmark
As soon as the field meets its rule (5 characters by default, or your pattern), its border turns green and a tick is drawn on the right.
Updated
This effect is part of Effect.Labs — 840 vanilla effects, some free, some premium. Forms has 20 effects, including 2 free. Explore the category →
3 usage examples



How it works
On every input event (typing, pasting, autofill), the script decides whether the field is good: length at least equal to its minlength attribute (5 in the shipped HTML) and no pattern, type or maxlength violation. The rules are the ones you write in the HTML, not a constant hidden in the script.
When the field becomes good, .okmk-group gets is-valid: green border and background, a tick fading in (0.3 s) while its stroke is drawn (stroke-dashoffset from 24 to 0 in 0.4 s, @keyframes okmk-draw). If it falls below the rule, everything goes back to neutral; next time, the tick is drawn again from the start.
The field has a real name and is sent with the form. A form reset clears the tick. Each .fx-0285-root works on its own; nothing is set on window.
Accessibility
- Field name: real label in a visually hidden
<label>("Code, at least 5 characters"), to adapt to your use; the placeholder is only a typing hint. - Success announced: a
role="status"region says "Valid" once, when the field turns green, without repeating on every key. The SVG tick isaria-hidden, so it is not read as an unnamed image. - Keyboard and touch: it is a standard text field, nothing depends on the mouse.
- Reduced motion: under
prefers-reduced-motion: reduce, the tick appears complete, with no drawing. - What the effect does not do: it shows no message while the entry is incomplete. To explain the rule, add visible help text under the field.
Browser compatibility
1.3 KB of JavaScript, CSS with variables, one inline SVG. Measured on 08/11/2026 in Chromium, Firefox and WebKit (Playwright): stroke still drawing 150 ms after turning green then complete, drawn again after clearing, two independent copies, value sent through FormData, touch at 390 px, reduced motion, no errors. Most recent feature used according to @mdn/browser-compat-data: minLength (Chrome 40, Firefox 51, Safari 10.1); NodeList.forEach needs Chrome 51.
Without JavaScript the field stays usable and the browser still enforces minlength and pattern on submit; only the tick is missing.
The code
HTML structure to paste into your page (the CSS + JS come with your purchase):
<div class="fx-0285-root">
<div class="okmk-group">
<label class="okmk-field">
<span class="okmk-sr">Code, at least 5 characters</span>
<input class="okmk-input" type="text" name="code" minlength="5" autocomplete="off" placeholder="Type 5+ characters">
</label>
<span class="okmk-check" aria-hidden="true">
<svg viewBox="0 0 24 24" focusable="false"><path d="M5 13l4 4L19 7"></path></svg>
</span>
<span class="okmk-sr" role="status"><span class="okmk-status-text" hidden>Valid</span></span>
</div>
</div>
One-time payment, no subscription — the code is yours forever
Customize
Options passed to the API or data-* attributes:
| Option / property | Default | Effect |
|---|---|---|
Validity rule (HTML — minlength, pattern, type, maxlength on the field) |
minlength="5", no pattern |
Without minlength, one character is enough. E.g. type="email" for an address, pattern="[0-9]{6}" for a code received by text message. |
Success colours (CSS — --okmk-ok, --okmk-ok-field on .fx-0285-root) |
#10b981 · 5% green | Colour of the border and tick, then the field background tint when it is good. |
Field at rest (CSS — --okmk-field, --okmk-border, --okmk-focus, --okmk-text) |
5% white · 10% white · #6366f1 · #fff | For a light form: --okmk-field:#fff; --okmk-border:#d6d3d1; --okmk-text:#1c1917. |
Width and text size (CSS — --okmk-width, --okmk-font-size) |
280px · 1rem | Width is a maximum: the field narrows in a tight column. 100% to follow its container. |
Demo frame (CSS — --okmk-bg, --okmk-min-height) |
#0a0a0f · 300px | On a real page: --okmk-bg:transparent; --okmk-min-height:0. |
Drawing speed (CSS — animation: okmk-draw .4s ease .05s) |
0.4 s after 50 ms | Lengthen to 0.6 s for a more visible tick on a large field. |
Announced text (HTML — .okmk-status-text) |
"Valid" | Replace with a meaningful message: "Postcode recognised", "Code accepted". |
FAQ
pattern (e.g. [0-9]{5}) and a minlength equal to the expected length; the tick only shows when both are met. An IBAN with a checksum needs an extra calculation: the effect only checks the shape.minlength and pattern, with its own bubble, once the user has edited the field. To drive a button (as in the danger zone), read the is-valid class on .okmk-group.okmk-draw animation is attached to the is-valid state only. Each time the field becomes good again, the stroke starts from zero; while it stays good, the tick holds still and nothing replays on every key.