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

Reply via email to