A red asterisk with no explanation, placed after the label in a colour that fails contrast and read aloud by screen readers as “star”, is the most common way forms say “required” — and many users do not know what it means until submitting shows them a wall of errors.

Users should learn what they must answer before they make a mistake. That needs a convention stated on the page, an indicator that is visible and understandable without colour, and markup that exposes the required state to assistive technology without doubling up. This page, part of error summary and messaging, compares the conventions and implements the one that works best for most forms.


Context and prerequisites

Two conventions, and a principle for choosing:

  • Mark required fields (usually with an asterisk). Works when most fields are optional. Needs an explanation at the top of the form (“Fields marked * are required”) and an accessible version of the marker.
  • Mark optional fields (“(optional)” after the label). Works when most fields are required — which is true of most well-designed forms, because optional questions should be rare. Needs no legend: the word explains itself.

Semantics:

  • required on a native input sets the accessible required state (announced as “required”), and enables native valueMissing validation unless the form has novalidate.
  • aria-required="true" sets the state without native validation — for custom controls or when you validate entirely in code.
  • Do not also put the word “required” in the label’s visible text and set required, or screen readers say “required” twice.
Two conventions compared Marking required fields with an asterisk fits forms where most fields are optional, needs a legend explaining the asterisk, and the asterisk should be hidden from screen readers because the required attribute already announces the state. Marking optional fields with the word optional fits forms where most fields are required, needs no legend, and is read naturally as part of the label, while required fields carry the required attribute. Aspect Mark required (*) Mark optional fits when most fields optional most fields required (usual) explanation legend needed self-explanatory screen reader hide *, rely on required "(optional)" read with label visual noise many asterisks few markers

The core pattern: mark optional fields, expose required state once

<form novalidate>
  <!-- Most fields are required: say nothing extra visually; set the state. -->
  <label for="full-name">Full name</label>
  <input id="full-name" name="full-name" autocomplete="name" required>

  <label for="email">Email address</label>
  <input id="email" name="email" type="email" autocomplete="email" required>

  <!-- The rare optional field says so in its label. -->
  <label for="company">Company name (optional)</label>
  <input id="company" name="company" autocomplete="organization">

  <!-- Groups: state the requirement in the legend; required on one radio. -->
  <fieldset>
    <legend>How should we contact you?</legend>
    <input type="radio" id="c-email" name="contact" value="email" required>
    <label for="c-email">Email</label>
    <input type="radio" id="c-phone" name="contact" value="phone">
    <label for="c-phone">Phone</label>
  </fieldset>
</form>
<!-- If you must use asterisks: explain them, and hide the glyph from AT. -->
<p class="form-legend">Fields marked with <span aria-hidden="true">*</span><span class="visually-hidden">an asterisk</span> are required.</p>
<label for="phone">Phone number <span class="req" aria-hidden="true">*</span></label>
<input id="phone" name="phone" type="tel" required>
.req { color: #8a1c14; font-weight: 700; }   /* ≥ 4.5:1; never the only signal */

Step-by-step walkthrough

  1. Reduce optional fields first. Every optional question is one users must decide whether to answer. Remove the ones you do not need; the rest become the exception.
  2. Mark the exception. If most fields are required, add “(optional)” to optional labels. If most are optional, mark required ones with an asterisk and explain it at the top.
  3. Set required (or aria-required) on required inputs. Screen readers announce “required” from the attribute; with novalidate, you keep your own error messages, per using the Constraint Validation API with custom form state.
  4. Hide decorative asterisks from assistive technology. aria-hidden="true" on the asterisk avoids “star” being read alongside the “required” state.
  5. State group requirements in text. Legends such as “How should we contact you?” plus required on one radio; for “at least one” groups, say so in the hint, as in requiring at least one of several fields.
  6. Write required messages as instructions. “Enter your full name”, not “Full name is required” — tell users what to do.

Why required markers matter for everyone, not only assistive technology

Required indicators are usually discussed as an accessibility feature, but their main benefit is planning. People filling in a long form decide how much effort to spend on each question and whether they have the information to hand — an account number, a reference, a document. Knowing up front which questions they can skip lets them gather what they need and move quickly through the rest. That is especially important for people with cognitive disabilities, anxiety about forms, or limited time, and it reduces the number of failed submits for everyone, which in turn reduces how often the error machinery — summaries, focus moves, announcements — has to run at all.

Which convention for this form? If the form has no optional fields at all, add a single sentence such as all fields are required, or nothing, and set required on each input. If most fields are required and a few are optional, mark the optional ones with the word optional in their labels. Otherwise, when most fields are optional, mark the required ones with an explained asterisk hidden from assistive technology, relying on the required attribute for screen readers. No optional fields? Set required; optional sentence at top yes no Most fields required? Mark optional fields yes no Asterisk, explained Legend at top; * hidden from AT.

Required state and error messages work together

The required indicator and the required-field error are two halves of one conversation. The indicator sets expectations before the user acts; the error explains, after a submit or blur, what is still missing. They should use consistent language: if the label says “(optional)” for the company field, no error should ever demand a company name; if a field is marked required, its empty-field message should name it and say what to enter. Consistency matters most in the error summary, where messages appear away from their labels — “Enter your full name” reads correctly there, while “This field is required” does not identify which field is meant. Keeping indicator, label and message aligned is easiest when all three are generated from the same field definition.


Failure modes and edge cases

1. Asterisk colour as the only signal

A red asterisk that fails contrast, or whose meaning is conveyed only by colour, fails for low-vision and colour-blind users. The asterisk must meet contrast and be explained in text.

2. “Required” said twice

<label>Email (required)</label><input required> makes screen readers say “Email required, edit text, required”. Choose one: the visible word or the attribute’s announcement — the attribute is usually enough.

3. Conditionally required fields

A field that becomes required when another answer changes should update its label marker and required state together, and never show a required error before the user has had a chance to answer, per conditional required fields without cycles.

4. Native validation bubbles

required without novalidate shows browser bubbles on submit, in the browser’s language and style. Add novalidate if you render your own errors.

5. Required but pre-filled

A required field with a default value is effectively satisfied. That can be right (a country defaulted from locale) or a trap (a pre-ticked consent box). Never pre-fill consent, and let users change defaults easily.

How a required field sounds The user tabs to the full name input, which has the required attribute and no visible marker; the screen reader says full name, edit text, required. The user tabs to the company input, whose label includes the word optional; the screen reader says company name optional, edit text. The asterisk variant, when used, is hidden from assistive technology, so the word star is never read. User Form Screen reader Tab to Full name (required attr) "Full name, edit text, required" Tab to Company (label says optional) "Company name (optional), edit text"

Verification checklist


Frequently Asked Questions

Is the asterisk convention understood well enough?

Many experienced web users recognise it, but not all users do, and its meaning is not obvious from the glyph. If you use it, explain it at the top of the form. Marking the (usually few) optional fields is clearer for most audiences.

Should I use aria-required or required?

Use required on native inputs; it provides both the accessible state and native validation (which novalidate can suppress). Use aria-required on custom widgets that are not native form controls, or when you want the state without any native behaviour.

How do I indicate required for a custom element?

A form-associated custom element can set internals.ariaRequired = "true" and report valueMissing through setValidity, so it behaves like a native required input, as in building Lit form controls with ElementInternals.


Related

← Error Summary and Messaging