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:
requiredon a native input sets the accessible required state (announced as “required”), and enables nativevalueMissingvalidation unless the form hasnovalidate.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.
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
- 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.
- 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.
- Set
required(oraria-required) on required inputs. Screen readers announce “required” from the attribute; withnovalidate, you keep your own error messages, per using the Constraint Validation API with custom form state. - Hide decorative asterisks from assistive technology.
aria-hidden="true"on the asterisk avoids “star” being read alongside the “required” state. - State group requirements in text. Legends such as “How should we contact you?” plus
requiredon one radio; for “at least one” groups, say so in the hint, as in requiring at least one of several fields. - 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.
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.
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.