In an existing web application, there are some accessibility concerns. Some views represent a collection of key-value pairs, for example, Name -> John Doe, Street -> Diagon Alley. At the moment they are only associated by position. They are above each other. How to link them with each other?
<div class="someClasses">
<label>name</label>
</div>
<div class="otherClasses">
<p>John Doe</p>
</div>
One solution would be to change the paragraph
to a disabled textfield and use the for tag. This may confuse how to enable them.
An other considered option is to use data lists (dl, dd, dt). When tested with the screenreader NVDA the association was not read.
Is there a better alternative?
No, there is no real better alternative than <dl>
, table, or fields associated with their label.
Depending on your case, I would recommend either to use read only input fields, or don't do anything special to precise the association.
You might think about using ARIA to make the association, something like this:
<span id="key">Key</span>
<span aria-labelledby="key">Value</span>
However, ARIA basically works only with interactive elements and landmarks, and this isn't the case here. Most screen readers will simply ignore it, so it's practically useless.
As a reminder, the first rule about ARIA says that you shouldn't use it if you don't really need to.
With read only input fields, the user might wonder how to make them modifiable, but the advantage of this construction is that the different keys/values can be read through with tab key.
According to WebAim surveys over the years, it doesn't change anything for experienced screen reader users who anyway don't primarily use tab, but it could help less experienced users, who are more likely to use tab.
Disabled input fields aren't focusable by default. They give no advantage over a definition list or a table. So it's a much less interesting construction.
If there are read only or disabled fields, the user can indeed wonder how to enable them or modify them.
In fact, I don't think it's a big problem, as long as your process is clear, and that the values are or were modifiable at some point in the application.
For example if your page with read only fields shows:
Then, you should anyway give information to the user telling them about the current state, and from there, it shouldn't be a surprise if the fields aren't modifiable / how to make them modifiable or where to go if possible.
However, when it becomes strange, is when the presented data aren't or weren't modifiable anywhere. In that case, it's effectively much better to not use input fields at all, to make it clear that the data have never been supposed to be entered by the user, or otherwise said, that the user has no control on it directly.
Using a table, having the keys in one column and the values in a second column for example, could be interesting. Screen readers allow to navigate tables by rows or columns, and automatically read header cells when navigating through data cells. So the association could be clearer that way.
<table>
<tr>
<th>Key 1</th>
<td>Value 1</td>
</tr><tr>
<th>Key 2</th>
<td>Value 2</td>
</tr>
</table>
Of course, the code is heavier, and harder to style...
Screen raders don't do anything special to link <dt>
and <dd>
currently, but we never know, it might be the case in the future.
With simple spans or unrelated elements, you can be sure that no progress can be made to show the association between key and value. Not today, and not tomorrow.
So, why not use a table ? or at least a definition list ? it should probably be preferred over simple spans.
Don't be so afraid, though. Screen reader user doesn't mean stupid, and, in most case, if the keys and values are following in alternation, we can make the link ourselves without additional help.
<label>
According to this question: Is using a label without any associated form element acceptable?
It's quite unclear if using <label>
without associated fields, explicitly or implicitly, is really valid.
Normally, a field should always be associated to a label, either explicitly:
<label for="x">text</label><input id="x" />
or implicitly:
<label>text
<input />
</label>
If you aren't inside one of the two patterns, it looks quite in the gray area of validity and good practice.
So if you don't have associated input fields, it's probably better to not use <label>
at all.
Anyway, it doesn't give any benefit in that case, and is semantically debattable.
If you are finally using simple spans or other inline elements, be careful about spacing.
<span>key</span>
<span>value</span>
Screen readers may read key and value glued together, as if you had written "keyvalue" in one word. It's at best unpleasant, and at worst it makes it ununderstandable. In case of doubt, use non breakable spaces (nbsp). Normal spaces can be automatically trimed.
<dl>
, <table>
, or simple spans, whatever you are currently already using, as there is anyway no better more precise solution