Skip to content
easeweb
Search topics

Split date and phone fields with no name for each box

A date of birth asked for in three dropdowns has one label, tied to the first, so a screen reader reads the month and the year with no name.

WCAG 2.2
SC 1.3.1ASC 3.3.2ASC 4.1.2A
Required by
Section 508 · EN 301 549 (EU)
Broken <label for="dob-day">
The accessibility problem illustrated: No vision:Is 05 the day or the month?
01

The problem

Screen reader users hear the month and the year as nameless dropdowns, and once all three hold numbers, nothing on screen says which is the day and which is the month.

02

Try it

Press Tab to move through the date of birth, and listen to what each box is called.

The date is already chosen. Below the form, check whether each box is read with a name, then look at the row: which box is the month?

Broken Can you fix this?

BrokenOne label above three dropdowns
/ /

Screen reader says:

(Tab to the date of birth)

A recreated demo. The broken version is intentionally inaccessible.

03

The fix

Name every box, and tie the set's label to all of them.

Before
BrokenOne label above three dropdowns
<label for="dob-day" class="field-label">Date of birth</label><div class="date-parts">  <select id="dob-day" name="dob-day">    <option value="">Day</option>    <option>01</option>    …  </select>  /  <select name="dob-month">    <option value="">Month</option>    <option>01</option>    …  </select>  /  <select name="dob-year">    <option value="">Year</option>    <option>2026</option>    …  </select></div>
What is wrong3 points

The first dropdown is named "Date of birth". The rest is where it fails.

  • The month and year dropdowns have no name, so a screen reader reads only "combo box" and the value.
  • Nothing groups the three, so "Date of birth" is never read with the month or the year.
  • The words Day, Month and Year are only the first options, and they disappear once a value is chosen.
After

A fieldset with a label on each box

<fieldset class="date-parts">  <legend class="field-label">Date of birth</legend>  <div class="date-part">    <label for="dob-day">Day</label>    <select id="dob-day" name="dob-day">      <option value="">Day</option>      <option>01</option>      …    </select>  </div>  <div class="date-part">    <label for="dob-month">Month</label>    <select id="dob-month" name="dob-month">      <option value="">Month</option>      <option>01</option>      …    </select>  </div>  <div class="date-part">    <label for="dob-year">Year</label>    <select id="dob-year" name="dob-year">      <option value="">Year</option>      <option>2026</option>      …    </select>  </div></fieldset>
How it is fixed4 steps
  1. Make the row a fieldset, so the three dropdowns are one group.
  2. Make "Date of birth" its legend, the group's name. A screen reader says it as focus enters the group, roughly "Date of birth, grouping, Day, combo box, 12".
  3. Give each dropdown an id and a visible label of its own: Day, Month and Year. They stay on screen once values are chosen, and voice control users can say "click Month".
  4. Drop the slashes: the labels now say what they said.

This fixes the Before and passes 1.3.1, 3.3.2 and 4.1.2. It is the pattern the GOV.UK date input and the US Web Design System's memorable date use, with a label above each part.

Why this fix: Use native HTML first

Easily confused
04

Design ideas

Split the date, but keep a word on every box.

Three ways to draw the same date of birth, with the day and the month filled in and the year empty. Tab through each and type a year: two keep a name on every box, and one loses them as you type.

In the design file

  • Draw the set filled in, and check every box still shows its name.
  • Write the question once, above the boxes, as the title of the set.
  • Put the boxes in the order your readers write dates, and keep the names whatever the order.
  • Draw the focus ring on each box, and an error on the one box that is wrong.
  • Write each label colour’s contrast ratio beside it, 4.5:1 or more (9.46:1 in the first sample).

Passes

  • Date of birth
    Label in a gap in each border Three outlined boxes, each with its name in a gap in its top border, 13px #4a4541 at 9.46:1 on white. The name sits there empty or filled, so the label never has to move, and the 1px #8f8882 edge holds 3.49:1.
  • Date of birth
    One pill, a name in each segment The three boxes drawn as one soft #f6f4f2 pill, split by thin lines, with each segment’s name small at its top, 13px #4a4541 at 8.63:1, and the value under it. It reads as one answer and still names every part; focus rings the one segment.

Fails

  • Date of birth
    The same pill with only DD, MM, YYYYWCAG 3.3.2 The same pill, with the grey letters DD, MM and YYYY inside the segments, #5c5650 at 6.60:1, and no names. Each set of letters goes as soon as a digit is typed, so the filled segments show 12 and 05 and nothing that says which is the month.
05

Verify the fix

4 checks, no mouse.

Test with: Keyboard, Screen reader, Zoom

0 of 4 checked

Record the OS, browser and assistive-technology versions, the build, the date, and the actual result of each step. Repeat after the shared date component changes.

Limits

This is a starting pattern, not a guarantee for every application. A screen reader reads a group's name as focus enters the group, so coming back with Shift + Tab from below, it is read with the year rather than the day, and some screen readers may repeat it on every part. The guide covers dates asked for in parts; a value split into one box per character, such as a one-time code, is covered in one-time code boxes that won't take a pasted code. Radio buttons and checkboxes under one question are covered in radio buttons and checkboxes without a group name. Test the complete form with your target assistive technology.

This is a recreated teaching example, not a finding about a named client. The code is a starting pattern: test it in your own product. No completed assistive-technology test is claimed here.

EaseWeb service

Fixed it? Keep it from coming back.

I turn guides like this one into rules your coding agents follow and checks your CI runs. Then I retest by hand with a keyboard and screen readers, periodically.

See the service