diff --git a/includes/form.inc b/includes/form.inc index 203afe985db..3fe577a7764 100644 --- a/includes/form.inc +++ b/includes/form.inc @@ -2986,6 +2986,9 @@ function theme_file($variables) { * for radio and checkbox #type elements as set in system_element_info(). * If the #title is empty but the field is #required, the label will * contain only the required marker. + * - invisible: Labels are critical for screen readers to enable them to + * properly navigate through forms but can be visually distracting. This + * property hides the label for everyone except screen readers. * - attribute: Set the title attribute on the element to create a tooltip * but output no label element. This is supported only for checkboxes * and radios in form_pre_render_conditional_form_element(). It is used @@ -3042,6 +3045,7 @@ function theme_form_element($variables) { $output .= ' ' . $element['#children'] . "\n"; break; + case 'invisible': case 'after': $output .= ' ' . $element['#children']; $output .= ' ' . theme('form_element_label', $variables) . "\n"; @@ -3128,10 +3132,15 @@ function theme_form_element_label($variables) { $title = filter_xss_admin($element['#title']); $attributes = array(); + // Style the label as class option to display inline with the element. if ($element['#title_display'] == 'after') { - // Style the label as class option to display inline with the element. $attributes['class'] = 'option'; } + // Show label only to screen readers to avoid disruption in visual flows. + elseif ($element['#title_display'] == 'invisible') { + $attributes['class'] = 'element-invisible'; + } + if (!empty($element['#id'])) { $attributes['for'] = $element['#id']; } diff --git a/modules/simpletest/tests/form.test b/modules/simpletest/tests/form.test index 60523f0a07a..20fbbb0f516 100644 --- a/modules/simpletest/tests/form.test +++ b/modules/simpletest/tests/form.test @@ -305,6 +305,9 @@ class FormsElementsLabelsTestCase extends DrupalWebTestCase { $elements = $this->xpath('//input[@id="edit-form-textfield-test-title-after"]/following-sibling::label[@for="edit-form-textfield-test-title-after" and @class="option"]'); $this->assertTrue(isset($elements[0]), t("Label after field and label option class correct for text field.")); + $elements = $this->xpath('//input[@id="edit-form-textfield-test-title-invisible"]/following-sibling::label[@for="edit-form-textfield-test-title-invisible" and @class="element-invisible"]'); + $this->assertTrue(isset($elements[0]), t("Label after field and label class is element-invisible.")); + $elements = $this->xpath('//label[@for="edit-form-textfield-test-title-no-show"]'); $this->assertFalse(isset($elements[0]), t("No label tag when title set not to display.")); } diff --git a/modules/simpletest/tests/form_test.module b/modules/simpletest/tests/form_test.module index b35e4325172..09ca8f81ccd 100644 --- a/modules/simpletest/tests/form_test.module +++ b/modules/simpletest/tests/form_test.module @@ -544,6 +544,11 @@ function form_label_test_form(&$form_state) { '#title' => t('Textfield test for title after element'), '#title_display' => 'after', ); + $form['form_textfield_test_title_invisible'] = array( + '#type' => 'textfield', + '#title' => t('Textfield test for invisible title'), + '#title_display' => 'invisible', + ); // Textfield test for title set not to display $form['form_textfield_test_title_no_show'] = array( '#type' => 'textfield',