Uniquely Labeling Fields in a Table
Many of my clients over the years have relied on fields in tables. Sometimes a checkbox to select a row, sometimes text inputs to update information, sometimes buttons select something. Rarely are they interested in a block of label text above the field, and I cannot disagree with them.
The challenge here is to create a unique name for each field without repeating text all over your screen. Experience has taught me that when clients try to visually hide <label>
text, it can fall out of sync with the column or row headers, making it even more confusing.
The good news here is that if you are creating tables correctly, there isn’t much extra work you need to do. Your column and row headers, paired with some ARIA, can do the job for you. I made a demo to show it in action, embedded below or directly at Codepen.
There are two sets of thing happening here:
- Each column needs a
<th>
and each row needs a<th scope="row">
, each with a uniqueid
attribute; - Each field needs an
aria-labelledby
pointing to theid
s of the column and row header (separated by a space).
The order of the id
values in the aria-labelledby
matters. Note that the aria-labelledby
code for the <button>
flips the order of the id
s referenced by aria-labelledby
in order to provide a more natural announcement to screen reader users (“Remove 1” versus “1 Remove”). The <button>
references its own id
attribute instead of the column header, though this is a decision you should make based on if the button text is different from the column header or likely to change based on errors or user input.
The fields are verbose for screen reader users who use table navigation, but that is a trade-off for users who tab through the fields. While this approach can make it a pain for voice users to select fields, hidden labels will always cause that challenge. An explanation of the naming convention can mitigate that.
Note that all the fields on this form are nonsense, the table is not responsive, and errors are not shown. These are strictly accessible, but maybe using row headers of strictly numbers is not the most usable option depending on your table. In no way would this example warrant an ARIA grid role.
Update: 22 June 2019
John made a great point in the comments. Maybe some of the labels would make more sense in my example if they pointed at the author name instead of an assigned number. After all, the row number announced with the assigned number feels like a permanent off-by-one error and may have muddied the point I was trying to make.
So I removed the first column, made the row header the second column, and used that as the assigned name. Note that in some browser and screen reader combinations, row headers that are not the first column are not announced for any cells in columns prior to the row header.
I also made a video.
4 Comments
I looked at this quickly because I had to get back to work but wouldn’t it be better connect the items to the author’s name instead of the row number, that way it would read “Remove Mary Shelley” instead of “Remove 2”?
In response to .Yes, John, yes it would.
Granted, each table would be different and, as you have pointed out, not every bit of labeling is best leaning on a row header when there is another cell that may make more sense in that context for those users.
For those following along, to make that work the
<td>
will also need a uniqueid
, which will then be referenced in thearia-labelledby
.
The fields are verbose for screen reader users who use table navigation, but that is a trade-off for users who tab through the fields.
Noting that as of NVDA 2023.3.3 + Chrome 122, tabbing is also quite verbose. From the first example, the following is announced when the first input is tabbed to:
“1 row 2 Claimed by column 7 1 Claimed by edit blank”
In response to .Yeah, I am working on a proposal that might make accNames for fields in tables come from column and row headers (in the absence of another method already in place). If I can come up with a viable model, and then browser support, hopefully stuff like you cite could be mooted.
Leave a Comment or Response