usds / us-forms-system

Build React forms with JSON Schema and the U.S. Web Design System
Other
139 stars 35 forks source link

[SCREENREADER]: Month, Day, Year combo box pattern not announcing LEGEND to assistive devices #265

Open 1Copenut opened 6 years ago

1Copenut commented 6 years ago

Issue

The Service Start and End Date month combo boxes do not read the "Service Start || End Date" labels out to screenreaders. Non-sighted users hear Month Combo Box, but do not know other than a month, day, or year what they should be entering. Screenshot attached below.

Acceptance Criteria

As a screenreader user, I want to hear Month, Day, Year, and the Service Start || End Date information read aloud.

Environment

Possible Fix

After doing some more research with various screenreader and browser combos, I determined adding an aria-describedby attribute to the <select> and <input> felt like the best approach.

This approach does cause the <legend> to be read twice in IE11 + JAWS if users don't navigate into the first input using TAB or DOWN_ARROW, but that verbosity is offset by increased context.

<div>
<legend class="schemaform-label" id="root_veteranDateOfBirth-label">
<!-- react-text: 267 -->Date of birth<!-- /react-text -->
  <span class="schemaform-required-span">(*Required)</span>
</legend>
<div class="schemaform-widget-wrapper">
  <div class="usa-date-of-birth row">
    <div class="form-datefield-month">
      <label class="input-date-label" for="root_veteranDateOfBirthMonth">Month</label>
      <select
        <!-- Added the aria-describedby here -->
        aria-describedby="root_veteranDateOfBirth-label"
        id="root_veteranDateOfBirthMonth"
        name="root_veteranDateOfBirthMonth">
          <option value="">
          </option>
          <option value="1">
            Jan
          </option>
          ...
          <option value="12">
            Dec
          </option>
      </select>
    </div>
    <div class="form-datefield-day">
      <label class="input-date-label" for="root_veteranDateOfBirthDay">Day</label>
      <select
        <!-- Added the aria-describedby here -->
        aria-describedby="root_veteranDateOfBirth-label"
        name="root_veteranDateOfBirthDay">
        <option value="">
        </option>
      </select>
    </div>
    <div class="usa-datefield usa-form-group usa-form-group-year">
      <label class="input-date-label" for="root_veteranDateOfBirthYear">Year</label>
      <input
        <!-- Added the aria-describedby here -->
        aria-describedby="root_veteranDateOfBirth-label"
        autocomplete="false"
        id="root_veteranDateOfBirthYear"
        max="3000" min="1900"
        name="root_veteranDateOfBirthYear"
        pattern="[0-9]{4}"
        type="number"
        value="">
    </div>
  </div>
</div>

44501306-bd6b6680-a65a-11e8-856b-e48ecb438dfa

dmethvin-gov commented 6 years ago

Thanks, this is great information!

To make it a bit more general, the problem is that we have a DateWidget with a <legend> describing the specific purpose of the data, then some rather generic <label>s that describe the individual components of the date (Month, Day, Year) but not its purpose.

If we go with the legend as the aria-describedby is it still clear enough which date component is which? Or would it be important to have it read the two concatenated together, "Service start date Year" for example?

1Copenut commented 6 years ago

By referencing the <legend> with the aria-describedby, the individual labels will be read out when the input receives focus, and then the legend text will be read out after a short pause. I have documented some research about current screen reader behavior v. the code change I proposed. I'll add a link to that research next week, so it can be easily referenced.

jcmeloni-usds commented 6 years ago

@1Copenut Echoing Dave's comments -- this is a great report and suggestion. Looking forward to more discussion. Thanks again!