#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.

Reply via email to