Form Controls with Labels in a Table
Sometimes it is necessary to have form controls within tables. And while tables provide their own labeling mechanism, it is important that each and every control still has its dedicated label.
Forms in tables are rather rare, but they can be a necessity. Be sure though you are using tables not simply for layout purposes – the days of layout tables are long gone. Forms in tables only make sense if they are handling data that has a tabular structure itself.
It is important that the table itself is marked up properly using table headers <th>
. This allows navigating the table (and the contained form controls) using desktop screen readers’ table navigation: simply press Ctrl + Alt + Up/Down/Left/Right
when inside a table.
But what about navigation in focus mode (using the Tab
key)?
We can fix this by simply adding real <label>
elements for each form control, then hide them visually
Working Example
Explanation
This makes the whole thing work in both Firefox and Internet Explorer, at least more or less: JAWS seems to have some trouble announcing the row headers in focus mode. But all in all, it is acceptable.
Code
<form>
<table>
<thead>
<tr>
<th>
Delivery provider
</th>
<th>
Insurance
</th>
<th>
Comment
</th>
</tr>
</thead>
<tbody>
<tr>
<th>
<input id="dhl" name="provider" type="radio" /><label for="dhl">DHL</label>
</th>
<td>
<input id="dhl_insurance" type="checkbox" /><label class="visually-hidden" for="dhl_insurance">Insurance</label>
</td>
<td>
<label class="visually-hidden" for="dhl_comment">Comment</label><textarea id="dhl_comment"></textarea>
</td>
</tr>
<tr>
<th>
<input id="ups" name="provider" type="radio" /><label for="ups">UPS</label>
</th>
<td>
<input id="ups_insurance" type="checkbox" /><label class="visually-hidden" for="ups_insurance">Insurance</label>
</td>
<td>
<label class="visually-hidden" for="ups_comment">Comment</label><textarea id="ups_comment"></textarea>
</td>
</tr>
<tr>
<th>
<input id="post" name="provider" type="radio" /><label for="post">Post</label>
</th>
<td>
<input id="post_insurance" type="checkbox" /><label class="visually-hidden" for="post_insurance">Insurance</label>
</td>
<td>
<label class="visually-hidden" for="post_comment">Comment</label><textarea id="post_comment"></textarea>
</td>
</tr>
</tbody>
</table>
</form>
.visually-hidden {
position: absolute;
width: 1px;
height: 1px;
left: -10000px;
overflow: hidden;
}
table {
border-collapse: collapse;
}
td, th {
border: 1px solid;
}
NIL