Example · Beginner

Contact form with an honest fallback

A labeled contact form that demonstrates native validation while clearly avoiding a false claim that messages are delivered.

Published
Last checked

What this demonstrates

Each control has a persistent label, useful type, stable name, and browser validation baseline.

Reviewed static previewOpen full preview

Field and label decisions

Each visible label is explicitly associated with one control. Placeholder text is not used as the only instruction because it disappears during entry and may be difficult to distinguish from a value. Stable name attributes give a future server endpoint predictable keys, while autocomplete tokens let the browser offer known contact details without guessing.

The email field uses type="email" to provide an appropriate mobile keyboard and a basic format check. The question remains a multiline textarea because its expected answer may be longer than one line. Required status is expressed with the native required attribute, so it is available programmatically as well as visually.

What native validation does and does not do

Native validation can identify an empty required control or an obviously malformed email before submission. It does not prove that an address exists, make submitted text safe, stop automated abuse, or replace server validation. Client checks improve recovery; the server remains responsible for accepting, normalizing, rejecting, and storing data safely.

Do not disable the submit button merely because the form is incomplete. A disabled control cannot explain what is missing. Let the person attempt the task, move focus to a useful error location, and preserve every valid value.

Submission contract

The preview deliberately has no action. It does not say a message was sent. A production version needs a same-origin or disclosed service endpoint, server validation, abuse protection, retention terms, and accessible error recovery.

Success copy must be tied to a confirmed response. A network timeout is not a success, and a client-side animation is not delivery evidence. If the service is unavailable, keep the entered values when safe, explain what happened, and offer a real alternative such as a disclosed email address.

Accessible error recovery

For a larger production form, add a concise error summary above the fields. Give the summary focus after a failed submission and link each message to its control. Keep an inline message beside the field, associate it with aria-describedby, and describe how to fix the value rather than only saying “invalid.”

Do not erase correct fields after one field fails. Do not announce an error solely through color. Re-test after server messages arrive, because server and browser wording can differ.

Test notes

Try submitting empty fields, an invalid email, and a complete form. The browser should identify missing information without erasing valid values.

Then test the same sequence with only a keyboard, at 200% zoom, at a 320 CSS pixel viewport, and with a screen reader. Confirm that the label, required state, instructions, error, and current value are announced together.

Production checklist

  • Connect the form to a documented HTTPS endpoint.
  • Validate, normalize, and limit every field on the server.
  • Add rate limiting or another proportionate abuse control.
  • Publish who receives the message and how long it is retained.
  • Return distinct success, validation, rate-limit, and service-failure states.
  • Prevent duplicate submissions without trapping someone after a failed try.

Known limitation

Native browser error presentation differs, so a real product may add a tested error summary without removing the native baseline.