Example of Error messages - default
<form className="bc-form"> <h2>User registration</h2> <BcPageAlert variant="error" role="alert" tabIndex={0} aria-labelledby="summary-error-msg-heading" > <h3 id="summary-error-msg-heading">2 errors have occurred</h3> <BcList as='ol' variant='number'> <BcList.Item> <a href="#account-email">Account email address</a> is invalid </BcList.Item> <BcList.Item> <a href="#terms-of-service-agreement">Terms of Service</a> was not agreed to </BcList.Item> </BcList> </BcPageAlert> <div className="bc-form__group"> <label htmlFor="account-email">Account email address</label> <BcTextInput name="account-email" id="account-email" type="email" isInvalid aria-describedby="account-email-error-msg" /> <div className="bc-form__error" id="account-email-error-msg" aria-live="polite" > <BcIcon variant="error"> Your account email must be a valid email address. </BcIcon> </div> </div> <div className="bc-form__group"> <label htmlFor="terms-of-service-agreement"> <BcControlInput name="terms-of-service-agreement" id="terms-of-service-agreement" isInvalid value="No" label="I agree to the Terms of Service" aria-describedby="tos-error-msg" /> </label> <div className="bc-form__error" id="tos-error-msg" aria-live="polite"> <BcIcon variant="error"> You must agree to the Terms of Service to register. </BcIcon> </div> </div> <BcButton type="submit">Submit</BcButton> </form>
React documentation
Last modified:
ℹ️ This feature doesn’t have a corresponding React component yet.
HTML
Last modified:
Wrap error messages in .bc-form__error
.
Use the .bc-icon--error
Icon component variant for the error message.
Error message code examples
Static on-submit
Begin by providing the error variant Page alert. This should:
- Provide a heading with an
id
noting that an error has occurred; give a count if there are numerous errors - Label the summary region using
aria-labelledby
, referencing the summary’s heading via itsid
- Set
role="alert"
on the summary region to relay to assistive technologies that important content has appeared - Ensure users can move keyboard focus to the page alert by giving it
tabindex="0"
- List the labels for the fields with errors and give a short summary of each error.
ℹ️ Implicit aria-live
value for alert
role: the alert
role has an implicit aria-live
value of assertive
which immediately calls out the region, irrespective of what a user was doing or where they had focus. Therefore it should only be applied to the form’s page alert error summary.
The list of errors should be given in the order in which they occur in the form.
Each list item label must link to the offending form field via its id
.
Each affected form field should provide a descriptive message to help users fill in the field correctly. To do this:
- Place the detailed error message directly beneath the offending form field
- Add an
id
to the error message - Add the
aria-describedby
attribute to the offending form field and reference theid
of its associated error message.
ℹ️ Adding error messages to Control inputs: When errors occur in a checkbox or radio button group it is recommended to link each option to the group’s error message by setting aria-describedby
and linking the id
of the error message. Do this for each <input>
in the group; not just the single, currently selected option.
Dynamic validation of user input
On-the-fly validation as a user completes each field
Validation is done as a user moves focus away from a field they have just interacted with.
When an error occurs Javascript is used to inject an appropriate message immediately in direct proximity to the offending field. To do this properly the browser needs to be informed that region of the page has new content, and that this content is related to a form field.
To add an on-the-fly error message to a form field:
- Place the error message directly beneath the offending form field
- Add
aria-live="polite"
to the error message - Add an
id
to the error message - Add the
aria-describedby
attribute to the offending form field and reference theid
of its associated error message.
⚠️ Avoid shouting at users: do not use aria-live="assertive"
for dynamically-added inline error messages, irrespective of the following approaches.
For example, suppose a user entered an invalid email address:
<form className="bc-form">
<div className="bc-form__group">
<label for="account-email">Account email address</label>
<input
className="bc-text-input bc-text-input--invalid bc-text-input--block"
name="account-email"
id="account-email"
type="email"
aria-invalid="true"
aria-describedby="account-email-error-msg"
/>
<div
className="bc-form__error"
id="account-email-error-msg"
aria-live="polite"
>
<span className="bc-icon bc-icon--error">
The account email must be a valid email address.
</span>
</div>
</div>
</form>
Note: the Page alert React component implements aria-live
via the liveRegion
prop.
Dynamic validation on-submit
Validation is done dynamically, en masse on-submit.
Because the validation is performed on all form fields at once, both a summary and the individual error messages must be given.
This method simply mixes the Static on-submit and On-the-fly methods. Follow the instructions for each of these.
For example, suppose a user submitted two errors in a user registration form that asks for a username, an email address, a password, and agreement to terms of service.
<form className="bc-form">
<h2>User registration</h2>
<!-- The summary: -->
<div
className="bc-page-alert bc-page-alert--error"
role="alert"
tabindex="0"
aria-labelledby="summary-error-msg-heading"
>
<h3 id="summary-error-msg-heading">2 errors have occured</h3>
<ol>
<li><a href="#account-email">Account email address</a> is invalid</li>
<li>
<a href="#terms-of-service-agreement">Terms of Service</a> was not
agreed to
</li>
</ol>
</div>
<!-- [Valid user name label and text field] -->
<!-- Invalid user email field: -->
<div className="bc-form__group">
<label for="account-email">Account email address</label>
<input
id="account-email"
type="email"
aria-invalid="true"
aria-describedby="account-email-error-msg"
/>
<div
className="bc-form__error"
id="account-email-error-msg"
aria-live="polite"
>
<span className="bc-icon bc-icon--error">
Your account email must be a valid email address.
</span>
</div>
</div>
<!-- [Valid user password label and text field] -->
<!-- Invalid ToS checkbox: -->
<div className="bc-form__group">
<label for="account-email">
<input
id="terms-of-service-agreement"
type="checkbox"
aria-invalid="true"
aria-describedby="tos-error-msg"
/>
<span>I agree to the Terms of Service</span>
</label>
<div className="bc-form__error" id="tos-error-msg" aria-live="polite">
<span className="bc-icon bc-icon--error">
You must agree to the Terms of Service to register.
</span>
</div>
</div>
</form>
Design
Last modified:
Accessibility
Last modified:
Rationale
Last modified:
Error messages let the user know that something has gone wrong after they’ve tried to do something.
There are three approaches to presenting error messages:
- Static on-submit, with errors raised after a page load
- Dynamically, on-the-fly as a user completes each field, with errors raised immediately
- Dynamically, on-submit, with errors raised without a page load.
- Use the
--error
variant of the Page alert component for error messages - Use and toggle the boolean
aria-invalid
attribute when an error occurs - Do not use
aria-errormessage
as it is not well supported.
See also
Last modified: