Drupal 7 Form API accessibility: #title_display

Drupal 7 comes with many accessibility improvements. One important improvement for module developers to be aware of allows for accessible names to be given to form elements, while allowing for flexibility in theming. You can read all about the change in #558928: Form element labeling is inconsistent, inflexible and bad for accessibility.

Accessible form elements

One of the steps required in order to ensure that a form can be used by all users is to provide an accessible name for each element in the form. WCAG 2.0 specifies:

4.1.2 Name, Role, Value: For all user interface components (including but not limited to: form elements, links and components generated by scripts), the name and role can be programmatically determined... (http://www.w3.org/TR/2008/REC-WCAG20-20081211/#ensure-compat-rsv)

name

text by which software can identify a component within Web content to the user

Note 1: The name may be hidden and only exposed by assistive technology, whereas a label is presented to all users. In many (but not all) cases, the label and the name are the same.
Note 2: This is unrelated to the name attribute in HTML. (http://www.w3.org/TR/2008/REC-WCAG20-20081211/#namedef)

The problem

When the #title property is set for a form element, it is automatically rendered by the form system. Sometimes developers wish to have more control over how #title is rendered than is available in Drupal 6. This is common when developers wish to have a form element and its title rendered in separate columns of a table. Have you ever written the following line of code?

unset($element['#title']);

You never need to do this again!

The #title_display property

Drupal 7 provides a #title_display property that can be used with any form element that supports the #title property. The #title_display property tells the form system how to render #title and supports four possible values.

before
(default) #title is rendered as a label element before the form element in the page markup.
after
#title is rendered as a label element after the form element in the page markup. (note: this is the default value for radio and checkbox form element types.)
attribute
(only applies to radio and checkbox elements) #title is rendered as the title attribute of the form element
invisible
#title is rendered as a label element before the form element in the page markup, and is made invisible with the Drupal 7 .element-invisible CSS class. This makes #title remain available to screen-reader users, but hides it from being displayed visually in the browser. You can read more about the .element-invisible class in: Drupal 7, two new system classes to improve accessibility.

There are still a number of ways in which the Form API can be improved to make it easier for developers to create accessible forms. Luckily discussion about this has already begun at Maintainers versus Architects in the Drupal Accessibility Group.