Broken aria-describedby in radios and checkboxes.

Created on 26 December 2016, about 8 years ago
Updated 20 March 2024, 10 months ago

Steps to reproduce

  1. Go to admin/config/people/accounts
  2. Navigate to REGISTRATION AND CANCELLATION > When cancelling a user account
  3. Inspect the radio buttons. Seeing that aria-describedby="edit-user-cancel-method--description" which edit-user-cancel-method--description doesn't exists.

Those 3 radio buttons don't have any description. So I think they don't need to have aria-describedby attribute.
For example, in REGISTRATION AND CANCELLATION > Who can register accounts?, the radio buttons don't have aria-describedby attribute since they don't have description.
However, the description below (Users with the Select method ...) is a description of the fieldset wrapper.

πŸ› Bug report
Status

Needs work

Version

11.0 πŸ”₯

Component
User moduleΒ  β†’

Last updated 6 days ago

Created by

Live updates comments and jobs are added and updated live.
  • Accessibility

    It affects the ability of people with disabilities or special needs (such as blindness or color-blindness) to use Drupal.

  • Needs tests

    The change is currently missing an automated test that fails when run with the original code, and succeeds when the bug has been fixed.

Sign in to follow issues

Merge Requests

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

  • πŸ‡¬πŸ‡§United Kingdom kalpaitch

    Following on from @codebymikey's point #29 I've also identified this happens to the 'container' element too, (albeit with the caveat that the container element does not support the #description attribute):

    $form['element'] = [
          '#type' => 'container',
          '#description' => 'A description added to the container.'
    ];
    

    This will result in a container wrapper being rendered with an incorrect 'aria-describedby' attribute.

    Following on from @andrewmacpherson's comment #22, I agree there needs to be a more extensible way to declare a form element as a composite form element. But there are also needs to be some consideration for other render elements which get the 'aria-describedby' attribute added.

  • πŸ‡¨πŸ‡¦Canada Liam Morland Ontario, CA πŸ‡¨πŸ‡¦

    Liam Morland β†’ made their first commit to this issue’s fork.

  • πŸ‡¨πŸ‡¦Canada Liam Morland Ontario, CA πŸ‡¨πŸ‡¦

    I have made a merge request with patch 17 rebased onto 11.x.

  • Pipeline finished with Success
    10 months ago
    Total: 505s
    #124455
  • Pipeline finished with Failed
    7 months ago
    #197329
  • Pipeline finished with Canceled
    7 months ago
    Total: 310s
    #197345
  • I agree with #25, that we should use something more extensible. However, I don't think either of the suggestions is enough information for making it work. The issue is in the FormBuilder class, and at that point, you don't have instances of ElementInterface, you have a render array. So you can't do an instanceof test.

    It might be easier to add an attribute #is_composite to the render array?

    Or if I'm wrong, then I would say it's probably better to have CompositeFormElementInterface, because there is also a CompositeFormElementTrait. So you could even put isComposite in the trait, and it would be added to any contrib/custom classes using the trait as well.

  • Pipeline finished with Success
    7 months ago
    Total: 542s
    #197353
  • πŸ‡ΊπŸ‡ΈUnited States jldust

    I agree that this needs to be more extensive, I'm seeing these broken references with selection options as well.

  • πŸ‡ΊπŸ‡ΈUnited States dcam

    For anyone who needs a workaround, you can implement this in a custom theme or module:

    /**
     * Implements hook_element_info_alter().
     */
    function my_theme_element_info_alter(array &$info) {
      $info['checkboxes']['#process'][] = '_my_theme_process_options_element';
      $info['radios']['#process'][] = '_my_theme_process_options_element';
    }
    
    /**
     * Processes checkboxes and radios elements.
     *
     * Checkboxes and radios have an accessibility bug where the child option
     * elements inherit an empty aria-describedby attribute from the parent.
     * Because the child elements are fully rendered before the parent, this can't
     * be handled in preprocess functions.
     *
     * @param array $element
     *   An options form element.
     *
     * @return array
     *   The processed options form element.
     *
     * @see https://www.drupal.org/project/drupal/issues/2839344
     */
    function _my_theme_process_options_element(array $element) {
      foreach ($element as $key => $value) {
        if (substr((string) $key, 0, 1) == '#') {
          continue;
        }
        if (!isset($value['#description']) && isset($value['#attributes']['aria-describedby'])) {
          unset($value['#attributes']['aria-describedby']);
          $element[$key] = $value;
        }
      }
      return $element;
    }
    

    The same thing can be accomplished by adding a process function to individual checkbox and radio buttons. I tested it. Doing that means you don't need to loop through all the keys in the parent element to find its children. But my preference was to target the checkboxes and radios since they're the ones that have the problem.

Production build 0.71.5 2024