Zoe asked a question on Twitter recently:
‘Sfunny—I had been pondering this exact question. In fact, I threw a CodePen together a couple of weeks ago.
Visually, both examples look the same; there’s a label, then a form field, then some extra text (in this case, a validation message).
The first example puts the validation message in an em
element inside the label
text itself, so I know it won’t be missed by a screen reader—I think I first learned this technique from Derek many years ago.
<div class="first error example">
<label for="firstemail">Email
<em class="message">must include the @ symbol</em>
</label>
<input type="email" id="firstemail" placeholder="e.g. you@example.com">
</div>
The second example puts the validation message after the form field, but uses aria-describedby
to explicitly associate that message with the form field—this means the message should be read after the form field.
<div class="second error example">
<label for="secondemail">Email</label>
<input type="email" id="secondemail" placeholder="e.g. you@example.com" aria-describedby="seconderror">
<em class="message" id="seconderror">must include the @ symbol</em>
</div>
In both cases, the validation message won’t be missed by screen readers, although there’s a slight difference in the order in which things get read out. In the first example we get:
- Label text,
- Validation message,
- Form field.
And in the second example we get:
- Label text,
- Form field,
- Validation message.
In this particular example, the ordering in the second example more closely matches the visual representation, although I’m not sure how much of a factor that should be in choosing between the options.
Anyway, I was wondering whether one of these two options is “better” or “worse” than the other. I suspect that there isn’t a hard and fast answer.