Last time I talked about the caption-detail structure and used it as an alternative way to mark up forms. I argued that a table is not the right semantical element for marking up a form, but that is not always correct. In some cases, a table is exactly what you need. So following up last week's article, this time I'll be looking into tabular forms and when to use them.
In some cases you want to ask the same batch of data multiple times, but for different entities. Not too long ago I was asked to make a form where a user could enter several "friends" of his which would all be contacted afterwards. The same 4 fields were required four each friend that was entered. You can see an example of the resulting form in the picture above. This of course is what tables were made for.
Still, there are a few hurdles to conquer before you can bring the structure above to an acceptable level of accessibility.
<!-- hurdle 1: heading for the table --> <tr><th>Title <span class="req">*</span></th></tr> <!-- hurdle 2: footer for the table --> <tr><td><a href="#">Add a friend</a></td></tr> <!-- hurdle 3: rows with fields --> <tr> <td> <label class="hidden" for="t1">Title (1) <span class="req">*</span></label> <select id="t1" name="t1">...</select> </td> </tr>
using header en footer
Placing the labels for the fields in the table headings sounds quite logical. Only problem is that by doing this you can only link the label to one input field. You can of course choose to link it to the first, but that means the following input elements wouldn't be connected at all. Not very good, that's why the heading elements don't hold any html labels, though they mimic the content of the labels, including the required field indicator.
screenreaders, forms and tables
Screenreaders often have two special modes. One mode to travel through forms, one to travel through tables. The code above pretty much covers the people going through the form in table mode. But we still need to connect a html label to each input field for people using the form mode. To do this, we simply add the label in front of each input field, use css to hide it (just reposition it) and make sure we repeat the required field indicator.
To finish it up, you can add a row number indication inside each label, to make it even clearer what input field the user is filling in. Since it is inside the hidden label it will not show up on screen, but it'll be of use to screenreader users.
So next time you run into a similar problem, don't fear the use of tables, but implement it well so screenreader users won't have any trouble navigating your form/table.
To get to this solution I was lucky enough to depend on the solid advise of the Anysurfer people, a very welcome organization in Belgium helping sites and designers to overcome accessibility issues. Cheers!