Group Labeling

Here we are trying to label a single input element with two different labels. This scenareo happens frequently in surveys where a form may have several questions each of which may have several answers from which to choose. When tabbing through a form such as this using a screen reader, typically only the answers will be read as you tab. This means that to complete the form, one needs to find and read the text of a question, then find the first answer in that question's answer group, go into forms mode, complete the answer, switch back out of forms mode, and find the next question and repeat. Using the technique shown here we can simply tab through the form and hear each question as it comes up.

*** One important thing to note here is the tradeoff between brevity and usability. As one tabs through the form, the goal is to be able to get enough context to complete the form with as little extraneous navigation as possible. If the questions are long (consider a multiple choice question such as one might find on a test), the question text as well as any or all of the individual answers may indeed be long, in which case it makes little sense to be forced to listen to the question before the current answer while tabbing through the form. This will inevitably lead to user fatigue and ultimately to user error.

It is also noted that styling forms, while still tricky, can give satisfactory results in modern browsers, especially for standard form widgets such as buttons, text fields, radio buttons, and checkboxes. For more complex widgets, there are available javascript solutions which can do a good job. If your site depends on javascript in order to function normally, then these libraries may fit in nicesly. You can find much more information in Advanced styling for HTML forms

Combining aria-labelledby and html label using the "for" attribute:

Here we label the first choice with a standard label, and add the aria-labelledby attribute which points back to the enclosing question. Neither Jaws nor NVDA correctly announce both labels; only the aria-labelledby label is read, the label applied via standard html label element is skipped.

Aria-labelledby only:

This one uses only aria-labelledby labels; no html label elements are used. Both Jaws and NVDA correctly read both labels on the first answer below. The downside of this implementation is twofold:
- only latest browser and screen reader combinations will do the right thing;
- you cannot mix aria and html labels (see the first approach above).
The fact that mixing approaches does not work may make this technique unsuitable for sites which use html label extensively.

Choice 1
Choice 2
Choice 3

This one Uses Fieldset / Legend:

This works with all browser /screen reader combinations. The downside is that many people do not like fieldsets perhaps for visual reasons, and you need to provide a legend which requires duplication of text, which can cause things to get out of sync if legend and question body are not both changed. For this reason, hiding the legend with CSS is possibly error prone, but will provide the best visual experience.

Another point to keep in mind about this technique is that it speaks the legend only when entering the fieldset from either end. This eliminates extraneous verbosity when tabbing through the form. In contrast, then following example speaks the entire contents of the heading, followed by the entire contents of the radio button's label each time tab is pressed. If the heading text is long (imagine a survey question, then this will be spoken prior to the radio button's label each time you tab, which can become quite tedious.

Question 3

This tecnhique uses aria-labelledby with html label elements which wrap their controls:

This technique wraps the input elements inside the label elements. Wrapping form controls inside label elements was the only use of the label element when it became available in html3, but was deprocated in html4 in favor of the for / id usage. HTML5 has brought it back. Its merrits are that it eliminates much of the need to create id strings for each labeled form control, which can be difficult to manage and consequently error prone. The only id required here is on the question heading itself.

*** Note that Jaws does not speak the label attached with aria-labelledby if an element in the group is checked!

*** Note: both labels are spoken each time a radio button gains focus. For this reason it may be advisable to only use aria-labelledby on the first and last button of the group (see previous technique).

This technique uses group role on container to provide context:

This technique is similar to the previous one, but has the advantage that only one reference need be made to the container label. Each input field need not refer directly to the container's label; this is implied.

Now if we could only do away with the ID strings on the container label itself! This is possible by using aria-label="string" on the container, but this is akin to using legend on a fieldset - the label must duplicate text which may already be part of the on-screen text which could lead to erroneous results if aria-label and on-screen text are not synchronized.

This technique uses hidden elements to provide missing context:

This last technique works in all browsers with CSS enabled which support CSS clip. The first label simply includes the text of the question, and it is clipped to invisibility using CSS clip. The downside is that the text of the question must be repeated in the label element, so conceivably one could make a change to the question text and forget to change the label text, thus producing an extremely confusing mess.