Cached forms can have duplicate HTML IDs, which disrupts accessible form labels

Created on 27 November 2012, over 12 years ago
Updated 22 February 2024, about 1 year ago

Problem/Motivation

In some scenarios, Drupal renders form elements with id attribute collisions (duplicate DOM ids).

This behavior has been observed when a cached page component, e.g. a search block or login block, is rendered in a new context.
In this case, Drupal's rudimentary duplicate-id-prevention mechanism fails, because the cached component is not re-analyzed for id collisions.

This is an acute accessibility problem, because id collisions interfere with field labeling, interactivity, and other a11y tools.

This can also can generate bugs in javascript, and stylesheet problems.

Steps to reproduce

  • Enable caching
  • Assign core search block to all pages
  • As anonymous, visit a page without any forms other than search block
  • Now, visit a page with search block and additional forms, e.g. login page

Expected behavior: all DOM elements will have unique ids
Observed behavior: conflicting DOM ids in common form elements, e.g. edit-actions

Proposed resolution

No consensus has been reached, but the following solutions have been proposed:

Viable solutions:

Update Html::getUniqueId() to generate a random ID every time, instead of naively incrementing an integer suffix.
Potentially, in order to maintain backwards compatibility, add a deprecation notice, and use an opt-in setting to enable/disable the behavior.

Rejected solutions:

  • id attribute is necessary for accessibility, to correlate labels and inputs

Workarounds

These workarounds have been suggested to temporarily work around the issue until a solution is available.

  • Cache all blocks per-url #33
  • Randomize ids with a hook_preprocess_container #37
  • Randomize ids with hook_preprocess_input #45

Remaining tasks

  • Decide how to fix the problem
  • Write a patch
  • Review
  • Change record

User interface changes

TBD

API changes

TBD

Data model changes

TBD

Release notes snippet

TBD

πŸ› Bug report
Status

Needs work

Version

11.0 πŸ”₯

Component
FormΒ  β†’

Last updated 1 day ago

Created by

πŸ‡ͺπŸ‡ΈSpain grisendo

Live updates comments and jobs are added and updated live.
  • Needs backport to D7

    After being applied to the 8.x branch, it should be considered for backport to the 7.x branch. Note: This tag should generally remain even after the backport has been written, approved, and committed.

  • Accessibility

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

  • Needs framework manager review

    It is used to alert the framework manager core committer(s) that an issue significantly impacts (or has the potential to impact) multiple subsystems or represents a significant change or addition in architecture or public APIs, and their signoff is needed (see the governance policy draft for more information). If an issue significantly impacts only one subsystem, use Needs subsystem maintainer review instead, and make sure the issue component is set to the correct subsystem.

  • Needs frontend framework manager review

    Used to alert the fron-tend framework manager core committer(s) that a front-end focused issue significantly impacts (or has the potential to impact) multiple subsystems or represents a significant change or addition in architecture or public APIs, and their signoff is needed (see the governance policy for more information). If an issue significantly impacts only one subsystem, use Needs subsystem maintainer review instead, and make sure the issue component is set to the correct subsystem.

Sign in to follow issues

Comments & Activities

Not all content is available!

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

  • I think this is a very serious issue. Especially if you are using modules like Fivestar or Rate where there may be a lot of forms on pages like Taxonomy pages where many nodes are shown with rating widgets.

    This happened to me on Drupal 10.2.3 website and it makes the website search and rating system not usable for most users.

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

    I haven't looked into whether this is viable yet, but we might be able to take a similar approach to #2463567: Push CSRF tokens for forms to placeholders + #lazy_builder β†’ - i.e. move the #id set in FormBuilder to lazily built placeholders.

    They'd have to be uncacheable and rely on a static cache of IDs that have already been built, but we already rely on that in the current logic so it's not making it worse.

    The case that this wouldn't cover is IDs added by AJAX, so is it really worth going to the trouble of a placeholder if it doesn't fix every case.

    I think we should just switch to a random suffix here. Yes it's possible that people are relying on hard-coded IDs, but that code is already buggy since those IDs could have a counter appended, so it shouldn't stop us from fixing the core bug.

Production build 0.71.5 2024