Skip to content
Style Guide
v0.1.0

Patterns

Form validation

When to check a field, how to word the message, and how to build an error summary that actually gets a person back to the problem.

When to validate

Timing matters more than styling. Validating too early is the most common way to make a form feel hostile — a field that turns red while someone is still typing their email is telling them they are wrong before they have finished being right.

MomentDoWhy
While typing, before the field has ever been valid Nothing Every partially typed value is invalid. Flagging it is noise.
On blur, after the person leaves the field Validate and show the error They have finished their attempt; now feedback is useful.
While typing, after an error is showing Re-validate and clear it as soon as it is fixed Confirms the fix immediately, without waiting for another blur.
On submit Validate everything, show the summary, move focus to it The last chance to catch fields never visited.
Live constraints (password rules, character counts) Show progress, not failure A checklist filling in reads as help; a red border reads as blame.

Field-level errors

The error sits directly below the field, linked with aria-describedby, and the field is marked aria-invalid="true". Three visual signals carry the state: the 2px border, the circled exclamation, and the message.

Enter an email address in the format name@example.com

Field error

aria-describedby takes a space-separated list, so a field can keep its help text and gain an error. Put the error id first — it is the more urgent of the two.

The error summary

On any form longer than about three fields, a summary at the top is what makes submission failures recoverable. Without it, a person whose screen shows the bottom of a long form gets no indication that anything happened at all.

Enter an email address in the format name@example.com

Enter a name for this device

Error summary

Four rules make the summary work:

  • Move focus to it on failed submit. It carries tabindex="-1" so it can receive focus programmatically without entering the tab order.
  • Every item is a link to the field's id. Following it puts the cursor in the field that needs fixing.
  • The link text is the error message, not the field name. It is the same sentence that appears beside the field, so the person is not translating between two wordings.
  • List them in the order they appear in the form.

Update the page title too — prefixing it with "Error: " tells someone who has switched tabs that the submission failed.

Wording

Start with a verb and say what to do. Do not describe what the person did wrong.

NotWrite
Invalid emailEnter an email address in the format name@example.com
This field is requiredEnter a name for this device
Password too weakUse at least 12 characters
Date is not validEnter a date in the future, such as 10 September 2026
Error 422: unprocessable entityWe could not save this device. Try again, or contact support with reference 422.

Say how many problems there are in the summary title — "There are 2 problems with this form" — and use the singular when there is one. It sets expectations before the person starts reading.

After a successful submit

  • Confirm it. A form that just closes leaves people unsure whether it worked.
  • If the page navigates, put a success alert at the top of the destination and move focus to the new page's heading.
  • If it stays, use a role="status" alert and move focus to it.
  • Say what happens next: "Saved. Your schedule runs from tomorrow."

Native validation

Use the HTML attributes — required, type, min, max, pattern. They give you free client-side checking and they inform assistive technology about the field's constraints even before anything is submitted.

Then add novalidate on the form and take over the display. The browser's own bubbles cannot be styled, disappear on their own, are inconsistent across browsers, and are not translated into Arabic reliably. Keep the attributes for their semantics; render the messages yourself.

Always validate on the server as well. Client-side validation is a courtesy to the person filling in the form, not a security control.

In Arabic

  • Error messages are translated properly, not machine-rendered from English. They are the sentences people read when they are already frustrated.
  • The error icon sits on the inline-start edge and moves with the direction — no change needed.
  • Format examples inside a message stay left-to-right. Wrap name@example.com in <span dir="ltr"> or the "@" and the dots land in the wrong places.
  • Never size a field or a message container to fit exactly one language's text.