#32819: Django forms - fields’ help text and errors should be associated with
input
-------------------------------------+-------------------------------------
Reporter: Thibaud Colas | Owner: nobody
Type: Bug | Status: new
Component: contrib.admin | Version: 3.2
Severity: Normal | Resolution:
Keywords: accessibility, ui, | Triage Stage:
forms | Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 1
-------------------------------------+-------------------------------------
Description changed by Thibaud Colas:
Old description:
> 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.
New description:
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:
[[Image(https://code.djangoproject.com/raw-attachment/ticket/32819/email-
required-ariadescribedby.gif)]]
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#comment:1>
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/070.20d0eb3cc41f5a69e6252437943d078c%40djangoproject.com.