Opened 3 years ago
Last modified 6 months ago
#32819 assigned Bug
Fields’ help text and errors should be associated with input
Reported by: | Thibaud Colas | Owned by: | David Smith |
---|---|---|---|
Component: | Forms | Version: | dev |
Severity: | Normal | Keywords: | accessibility, ui, forms |
Cc: | Triage Stage: | Accepted | |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | yes |
Easy pickings: | no | UI/UX: | yes |
Description (last modified by )
With Django’s default field rendering, all field errors are rendered as a list above the field’s label, and help text is rendered after the field’s form element. Example with as_p
:
<ul class="errorlist"> <li>This field is required.</li> </ul> <p> <label for="id_duration_required">Duration required:</label> <input type="text" name="duration_required" required="" id="id_duration_required"> <span class="helptext">Help</span> </p>
One problem for screen reader users is that the association between the errors and the field, and between the help text and the field, is only communicated visually. This is a failure of either WCAG 2.1 level A SC 1.3.1: Info and Relationships, or SC 3.3.2: Labels or Instructions. More importantly, it just makes it harder than necessary for screen reader users to make use of help text, and to identify error messages.
The fix is relatively straightforward – using aria-describedby
, as documented in the (non-normative) ARIA1 Using the aria-describedby property to provide a descriptive label for user interface controls technique. Here is another well-known accessibility-oriented UI library that implements this technique: GOV.UK design system – text input with error message.
Here is what implementing aria-describedby
would look like in the same example as above:
<div class="errorlist" id="id_duration_required_errorlist"> <p>This field is required.</p> </div> <p> <label for="id_duration_required">Duration required:</label> <input type="text" name="duration_required" required="" id="id_duration_required" aria-describedby="id_duration_required_errorlist id_duration_required_helptext"> <span class="helptext" id="id_duration_required_helptext">Help</span> </p>
We have additional id
attributes, aria-describedby
, and errorlist
is no longer a <ul>
. Result in VoiceOver:
Unfortunately I tried to have this with the errorlist
kept as a ul
, but it wasn’t announced by VoiceOver. I haven’t heard of this limitation before so am not sure why that might be the case – I’d appreciate others taking a look if possible.
Attachments (1)
Change History (30)
by , 3 years ago
Attachment: | email-required-ariadescribedby.gif added |
---|
comment:1 by , 3 years ago
Description: | modified (diff) |
---|
comment:2 by , 3 years ago
Component: | contrib.admin → Forms |
---|
comment:3 by , 3 years ago
Summary: | Django forms - fields’ help text and errors should be associated with input → Fields’ help text and errors should be associated with input |
---|---|
Triage Stage: | Unreviewed → Accepted |
Thanks. Ideally, we should avoid changing <ul>
to <div>
. Maybe <ul>
could be wrapped by <div>
.
comment:4 by , 3 years ago
Owner: | changed from | to
---|---|
Status: | new → assigned |
I created a draft PR.
@Mariusz, Could you please check it and let me know if I choose the right direction to fix the problem? If so, I can continue with test adjustment.
@Thibaud, It would be great if you can if it will produce your desired output.
comment:5 by , 3 years ago
Owner: | removed |
---|---|
Status: | assigned → new |
comment:6 by , 3 years ago
Owner: | set to |
---|---|
Status: | new → assigned |
comment:7 by , 2 years ago
Owner: | changed from | to
---|
comment:9 by , 18 months ago
Owner: | changed from | to
---|
comment:10 by , 18 months ago
Patch needs improvement: | unset |
---|
comment:12 by , 18 months ago
Version: | 3.2 → dev |
---|
comment:13 by , 18 months ago
Patch needs improvement: | set |
---|
Note that the PR focuses on solving this issue for help_text
.
comment:14 by , 17 months ago
Patch needs improvement: | unset |
---|---|
Triage Stage: | Accepted → Ready for checkin |
comment:16 by , 16 months ago
Resolution: | fixed |
---|---|
Status: | closed → new |
Reopening as the errors case still requires fixing.
comment:17 by , 16 months ago
Has patch: | unset |
---|---|
Triage Stage: | Ready for checkin → Accepted |
comment:18 by , 12 months ago
Has patch: | set |
---|---|
Owner: | changed from | to
Status: | new → assigned |
comment:21 by , 12 months ago
Triage Stage: | Accepted → Ready for checkin |
---|
comment:24 by , 12 months ago
Has patch: | unset |
---|---|
Triage Stage: | Ready for checkin → Accepted |
comment:25 by , 11 months ago
Has patch: | set |
---|
comment:26 by , 10 months ago
Patch needs improvement: | set |
---|
Setting as patch needs improvement because the docs for when a custom aria-describedby
is given definitely needs more details/clarification about what the user should do to properly customize the attribute for help text and errors.
comment:27 by , 7 months ago
Patch needs improvement: | unset |
---|
PR to avoid adding aria-describedby
to hidden
inputs.
comment:29 by , 6 months ago
Patch needs improvement: | set |
---|
Screen recording of the VoiceOver text-to-speech output, announcing the field label, then error message, then help text.