Forms without an accessible name should not have a landmark role

#525393430 Regression in 149.0.7819.0 Original: #40852121

Summary

Starting with Chrome 149, every native <form> element is exposed with a form landmark role even when it has no accessible name. Screen readers (NVDA in browse mode, VoiceOver) announce a form region on entering and leaving every such form, which is significant browse-mode navigation noise.

Per HTML-AAM, a <form> maps to the form landmark role only when it has an accessible name from aria-label, aria-labelledby, or title. Without a name it must be a generic container, not a landmark.

Live demo

The two forms below are the repro. Navigate them with a screen reader, or inspect them in chrome://accessibility.

Case 1: no accessible name — must NOT be a landmark
Case 2: aria-label present — SHOULD be a form landmark

Steps to reproduce

1. Load this page (or the minimal markup below).

2. Open chrome://accessibility/, enable "Internal", select this tab, click "show accessibility tree".

3. Inspect the first <form> (no accessible name).

<!-- Case 1: no accessible name. Per HTML-AAM must NOT be a landmark. -->
<form action="#">
  <label>Search <input type="search" name="q"></label>
  <button type="submit">Go</button>
</form>

<!-- Case 2: accessible name present. SHOULD be a form landmark. -->
<form action="#" aria-label="Newsletter signup">
  <label>Email <input type="email" name="email"></label>
  <button type="submit">Subscribe</button>
</form>

Expected vs actual

Platform / APICase 1 (unnamed) — expectedCase 1 — actual (149+)
Windows IA2 (NVDA)IA2_ROLE_SECTIONIA2_ROLE_FORM (announced as form)
Windows UIAno landmarkUIA_FormLandmarkTypeId
macOS (VoiceOver)AXGroup (group)AXSubrole=AXLandmarkForm
Linux ATKATK_ROLE_FORM (not landmark)ATK_ROLE_FORM (already correct)

Case 2 (named) is exposed as a form landmark on all platforms, which is correct.

Root cause

Regressed by CL 7257274 (bug 468317749), which made Blink always return Role::kForm for <form> and pushed the named/unnamed decision to each platform.

The platform mappings used the wrong signal. Because IsLandmark(kForm) is true, Blink serializes xml-roles="form" (the kRole attribute) on every kForm node, so a kName || kRole check can never demote an unnamed native form.

Windows IA2 (used by NVDA) was never updated, Windows UIA keyed off kRole, and the macOS fix was applied to the Views class instead of the web-content class. Only Linux/ATK (name-only) was correct.

Fix

Use the accessible name as the sole signal on every platform, matching the shipping Linux behavior: an unnamed <form> becomes a plain section/group, a named one stays a form landmark.

// ax_platform_node_win.cc  (ComputeIA2Role)
case ax::mojom::Role::kForm:
  ia2_role = HasStringAttribute(ax::mojom::StringAttribute::kName)
                 ? IA2_ROLE_FORM
                 : IA2_ROLE_SECTION;
  break;

Links

Issue: #525393430 (regression) · #40852121 (original)

Regressing CL: crrev.com/c/7257274

Spec: HTML-AAM <form> · Core-AAM