[whatwg] Form Control Group Labels

Matthew Raymond mattraymond at earthlink.net
Thu Nov 2 04:05:28 PST 2006


Lachlan Hunt wrote:
> Matthew Raymond wrote:
>> Example:
>>
>> | <p>
>> |   <label group="gender">Gender:</label>
>> |
>> |   <label for="m">
>> |     <input type="radio" id="m" name="gender" value="m">
>> |     Male
>> |   </label>
>> |
>> |   <label for="f">
>> |     <input type="radio" id="f" name="gender" value="f">
>> |     Female
>> |   </label>
>> | </p>
> 
> I just realised a problem with this proposal.  What if we want to 
> associate a label with several controls, with different names?  Here's a 
> few use cases:
> 
> 
> 1. Seperate fields for a date (day, month, year)
> Note: I'm aware that type="date" solves this specific use case, but this 
> is still a very commonly used structure today and illustrates my point 
> nicely.
> 
> <label group=" ? ">Birthday:</label>
> <label for="day"> day:
>     <input type="text" name="bday-day" id="day"></label>
> 
> <label for="month"> month:
>    <select name="bday-month" id="month">
>      <option>January</option>
>      ...
>    </select>
> </label>
> 
> <label for="year">year:
>    <input type="text" name="bday-year" id="year"></label>

   Just use space separation like in |class| attributes:

| <label group="day month year">Birthday:</label>
| <label for="day"> day:
|   <input type="text" name="bday-day" id="day">
| </label>
|
| <label for="month"> month:
|   <select name="bday-month" id="month">
|     <option>January</option>
|     ...
|   </select>
| </label>
|
| <label for="year">year:
|   <input type="text" name="bday-year" id="year">
| </label>

> Note: It's also possible to solve that particular case using 
> <legend>Birthday</legend> in a fieldset.

   Yeah, this is getting very close to <fieldset> territory. We should
be careful about defining new markup just because we don't like the
default styling in most browsers.

> 2. Another use case is, which can't be solved using fieldset and legend, 
> is a table of input elements, like this:
> 
> The inputs could be checkboxes, text fields or whatever.
> 
> <table>
> <thead>
>    <tr>
>      <th><label group=" ? ">Apples</label>
>      <th><label group=" ? ">Oranges</label>
>      <th><label group=" ? ">Bananas</label>
> <tbody>
>    <tr>
>      <th scope="row"><label group=" ? ">Foo</label>
>      <td><input name="foo-apple">
>      <td><input name="foo-orange">
>      <td><input name="foo-banana">
>    <tr>
>      <th scope="row"><label group=" ? ">Bar</label>
>      <td><input name="bar-apple">
>      <td><input name="bar-orange">
>      <td><input name="bar-banana">
>    <tr>
>      <th scope="row"><label group=" ? ">Baz</label>
>      <td><input name="baz-apple">
>      <td><input name="baz-orange">
>      <td><input name="baz-banana">
> </table>

   Yeah, I can see use cases where the data is actually tabular in
nature. I'm not sure, however, why the column header can't be used to
label the group in this case:

| <table>
| <thead>
|    <tr>
|      <th scope="col">Apples
|      <th scope="col">Oranges
|      <th scope="col">Bananas
| <tbody>
|    <tr>
|      <th scope="row">Foo
|      <td><input name="foo-apple">
|      <td><input name="foo-orange">
|      <td><input name="foo-banana">
|    <tr>
|      <th scope="row">Bar
|      <td><input name="bar-apple">
|      <td><input name="bar-orange">
|      <td><input name="bar-banana">
|    <tr>
|      <th scope="row">Baz
|      <td><input name="baz-apple">
|      <td><input name="baz-orange">
|      <td><input name="baz-banana">
| </table>

   The above markup is HTML 4.01 and effectively labels the all content.
Perhaps I'm missing something, but I don't see why the <th> elements
aren't good enough to be treated as group labels in the above case.

   That said, |class|-style space separation works here too:

| <table>
| <thead>
|    <tr>
|      <th scope="col">
|        <label group="foo-apple bar-apple baz-apple">Apples</label>
|      <th scope="col">
|        <label group="foo-orange bar-orange baz-orange">Oranges</label>
|      <th scope="col">
|        <label group="foo-banana bar-banana baz-banana">Bananas</label>
| <tbody>
|    <tr>
|      <th scope="row">
|        <label group="foo-apple foo-orange foo-banana">Foo</label>
|      <td><input name="foo-apple">
|      <td><input name="foo-orange">
|      <td><input name="foo-banana">
|    <tr>
|      <th scope="row">
|        <label group="bar-apple bar-orange bar-banana">Bar</label>
|      <td><input name="bar-apple">
|      <td><input name="bar-orange">
|      <td><input name="bar-banana">
|    <tr>
|      <th scope="row">
|        <label group="baz-apple baz-orange baz-banana">Baz</label>
|      <td><input name="baz-apple">
|      <td><input name="baz-orange">
|      <td><input name="baz-banana">
| </table>

   Still, I think a solution integrated into the tabular markup would be
preferable. Any other kind of solution is going to be verbose and awkward.

> I've come across this issue before, but the only accessible way to solve 
> it that I know of is to add an individual label for every input and then 
> hide it using CSS, so that it's read by screen readers but hidden to 
> visual UAs.

   That would be verbose and awkward. ;)

> It could possibly be argued that [assistive] technology should just get 
> smarter, and know that it should associate <th> elements with the form 
> controls and read them out like labels, but AFAIK, they don't.  We 
> should try to get some feedback from people who know more about 
> accessibility than we do.

   Oops! Should read the whole message before replying. Yeah, I'm not
sure screen readers would benefit from new markup when they don't take
full advantage of old markup. It's unlikely that authors are going to
get less lazy and start using <label group=""> in tabular situations
such as these, but it is possible that HTML tools could intelligently
insert |scope| attributes into <th> elements.

> Now, all of a sudden, the mistakes I made in my initial examples with 
> the erroneous info attributes don't look too bad.  Maybe we do need to 
> add a separate attribute to form controls for logically grouping them 
> and associating them with a group label.

   Anything more extensive than the two examples you gave probably needs
at least one <fieldset>. If you're creating huge, odd-shaped and
segmented groups all over the place, you should probably rethink your
form structure, because it probably doesn't make sense to the user. An
|info|-type attribute is too powerful and requires too much work of the
author. I'd rather see |name| pattern matching than an attribute on
every control element, because it forces the author to think about the
control hierarchy.



More information about the whatwg mailing list