#32819: Django forms - fields’ help text and errors should be associated with
input
-------------------------------------+-------------------------------------
Reporter: Thibaud | Owner: nobody
Colas |
Type: Bug | Status: new
Component: | Version: 3.2
contrib.admin | Keywords: accessibility, ui,
Severity: Normal | forms
Triage Stage: | Has patch: 0
Unreviewed |
Needs documentation: 0 | Needs tests: 0
Patch needs improvement: 0 | Easy pickings: 0
UI/UX: 1 |
-------------------------------------+-------------------------------------
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
[https://www.w3.org/WAI/WCAG21/Understanding/info-and-relationships.html
SC 1.3.1: Info and Relationships], or
[https://www.w3.org/WAI/WCAG21/Understanding/labels-or-instructions 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)
[https://www.w3.org/WAI/WCAG21/Techniques/aria/ARIA1.html 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: [https://design-
system.service.gov.uk/components/text-input/#error-messages 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:
Screen recording of the VoiceOver text-to-speech output, announcing the
field label, then error message, then help text.
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.
--
Ticket URL: <https://code.djangoproject.com/ticket/32819>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
--
You received this message because you are subscribed to the Google Groups
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/django-updates/055.c97c89d1a9d4fba088c70400eed8dc59%40djangoproject.com.