Say what the browser gives a popover trigger, and pin the part all engines can prove #94

Merged
lilleman merged 1 commits from popover-expanded into main 2026-08-26 15:37:06 +02:00
Owner

The dropdown rule said we omit aria-expanded because "a zero-JS invoker cannot keep it truthful". True, but it is the weaker half and it reads as a limitation we accept. The real reason is that the browser maintains it for us on a declarative popovertarget invoker, in all four engines — so writing one by hand would replace a live state with a static lie.

Measured on a real page, JavaScript disabled, reading Chromium's own accessibility tree over CDP rather than trusting docs:

CLOSED    >>> role=button name="Epic" focusable=true              expanded=false
OPEN      >>> role=button name="Epic" focusable=true focused=true expanded=true
DISMISSED >>> role=button name="Epic" focusable=true focused=true expanded=false

No aria-expanded anywhere in the HTML; the state is correct anyway and tracks Esc.

The clause worth having is the one that stops a future mistake: that guarantee belongs to the declarative attribute alone. Open a panel from script and no engine applies it — so "enhancing" one of these triggers is precisely what would cost it its accessibility. That inverts the usual instinct, which is why it belongs written down.

No test for the expanded state itself. Reading it needs CDP, which is Chromium-only, and visual.spec.ts is the suite that deliberately runs all three engines because popover and anchor positioning are where they disagree — a Chromium-only assertion there would give false comfort. Pinned the cross-engine half instead: focus returns to the trigger after Esc, which is the same browser-provided contract and passes in chromium, firefox and webkit. Say the word if you want the CDP check as a separate chromium-gated test.

Full gate green.

The dropdown rule said we omit `aria-expanded` because "a zero-JS invoker cannot keep it truthful". True, but it is the weaker half and it reads as a limitation we accept. The real reason is that **the browser maintains it for us** on a declarative `popovertarget` invoker, in all four engines — so writing one by hand would replace a live state with a static lie. Measured on a real page, JavaScript disabled, reading Chromium's own accessibility tree over CDP rather than trusting docs: ``` CLOSED >>> role=button name="Epic" focusable=true expanded=false OPEN >>> role=button name="Epic" focusable=true focused=true expanded=true DISMISSED >>> role=button name="Epic" focusable=true focused=true expanded=false ``` No `aria-expanded` anywhere in the HTML; the state is correct anyway and tracks Esc. The clause worth having is the one that stops a future mistake: **that guarantee belongs to the declarative attribute alone.** Open a panel from script and no engine applies it — so "enhancing" one of these triggers is precisely what would cost it its accessibility. That inverts the usual instinct, which is why it belongs written down. **No test for the expanded state itself.** Reading it needs CDP, which is Chromium-only, and `visual.spec.ts` is the suite that deliberately runs all three engines because popover and anchor positioning are where they disagree — a Chromium-only assertion there would give false comfort. Pinned the cross-engine half instead: focus returns to the trigger after Esc, which is the same browser-provided contract and passes in chromium, firefox and webkit. Say the word if you want the CDP check as a separate chromium-gated test. Full gate green.
lilleman added 1 commit 2026-08-26 09:10:48 +02:00
Say what the browser gives a popover trigger, and pin the part all engines can prove
CI / full-gate (push) Successful in 2m51s
Mirror / github-mirror (push) Successful in 3s
0ad4c6b09c
lilleman merged commit 0ad4c6b09c into main 2026-08-26 15:37:06 +02:00
lilleman deleted branch popover-expanded 2026-08-26 15:37:07 +02:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: larvit/plainpages#94