Android: the queue's scrim has no reachable pixels, so tap-outside-to-close does not exist #171

Closed
opened 2026-08-21 02:16:47 +00:00 by logan · 2 comments
Collaborator

Report

queue-panel's scrim has zero reachable pixels below 600px, so
#24's "click outside to close" affordance does not exist on a phone.

Measured on the running app at 424x439 with the queue open:

element rect
queue-panel host 424 x 318
.panel-content 424 x 318
.scrim 424 x 318, entirely underneath .panel-content

Findings

  • It is not a bug in either rule, it is the two meeting. The host spans
    the content area and draws the scrim across all of it; the phone rule
    :host([overlay]) .panel-content { width: 100% } then covers the
    scrim completely. Both are correct on their own and were added in the
    same change.
  • The scrim is still doing its other job at 600–899px, where the panel
    is 320px of a wider content area, so this is not "delete the scrim".
  • queue-overlay.spec.ts asserts the scrim closes the panel at
    900x600 only
    , which is the band where it is reachable — so the suite
    is honest and simply does not cover the phone. A phone-width case
    added naively would click the scrim's centre and hit the panel.
  • #55 makes this survivable rather than fixing it: back closes the queue
    now, and the close button is 44x44. So the routes out are fine; what
    is missing is the affordance #24 argued for, which is that an overlay
    should read as something you dismiss by tapping past it.

Direction

Either give the phone's panel a gutter — the platform pattern, and it is
what makes "tap past it" possible at all — or state that below 600px the
scrim is a dimming layer with no dismissal role and stop drawing it as a
button there. The first is a design decision about a full-screen surface
that #59 also touches; the second is honest and free. Decide which
before writing the spec, because the spec is different in each case.

**Report** `queue-panel`'s scrim has **zero reachable pixels below 600px**, so #24's "click outside to close" affordance does not exist on a phone. Measured on the running app at 424x439 with the queue open: | element | rect | |---|---| | `queue-panel` host | 424 x 318 | | `.panel-content` | 424 x 318 | | `.scrim` | 424 x 318, entirely underneath `.panel-content` | **Findings** - It is not a bug in either rule, it is the two meeting. The host spans the content area and draws the scrim across all of it; the phone rule `:host([overlay]) .panel-content { width: 100% }` then covers the scrim completely. Both are correct on their own and were added in the same change. - The scrim is still doing its other job at 600–899px, where the panel is 320px of a wider content area, so this is not "delete the scrim". - `queue-overlay.spec.ts` asserts the scrim closes the panel **at 900x600 only**, which is the band where it is reachable — so the suite is honest and simply does not cover the phone. A phone-width case added naively would click the scrim's centre and hit the panel. - #55 makes this survivable rather than fixing it: back closes the queue now, and the close button is 44x44. So the *routes out* are fine; what is missing is the affordance #24 argued for, which is that an overlay should read as something you dismiss by tapping past it. **Direction** Either give the phone's panel a gutter — the platform pattern, and it is what makes "tap past it" possible at all — or state that below 600px the scrim is a dimming layer with no dismissal role and stop drawing it as a button there. The first is a design decision about a full-screen surface that #59 also touches; the second is honest and free. Decide which before writing the spec, because the spec is different in each case.
logan self-assigned this 2026-08-21 11:32:41 +00:00
logan added the
Status
In Progress
label 2026-08-21 11:32:41 +00:00
Author
Collaborator

Picking this up on branch fix/171-phone-queue-scrim.

Taking the second of the two directions, not the gutter.

Below 600px the queue is a screen: #55 made it a place with a history
entry, back closes it, and the close button is 44x44. A gutter is the
drawer pattern, and it would trade width off a full-screen surface on a
424px viewport to buy an affordance the screen model does not ask for.

So the scrim is simply not drawn at phone width — it dims nothing there
(measured entirely underneath an opaque .panel-content) and dismisses
nothing, so drawing it as a cursor: pointer click target is a claim the
component cannot keep. Existence from matchMedia rather than a media
query, on job-band/search-trigger's rule: a stylesheet does not get to
decide whether an element exists. The 600-899px band, where the scrim has
real uncovered pixels, is untouched.

Picking this up on branch `fix/171-phone-queue-scrim`. **Taking the second of the two directions**, not the gutter. Below 600px the queue is a *screen*: #55 made it a place with a history entry, back closes it, and the close button is 44x44. A gutter is the drawer pattern, and it would trade width off a full-screen surface on a 424px viewport to buy an affordance the screen model does not ask for. So the scrim is simply not drawn at phone width — it dims nothing there (measured entirely underneath an opaque `.panel-content`) and dismisses nothing, so drawing it as a `cursor: pointer` click target is a claim the component cannot keep. Existence from `matchMedia` rather than a media query, on `job-band`/`search-trigger`'s rule: a stylesheet does not get to decide whether an element exists. The 600-899px band, where the scrim has real uncovered pixels, is untouched.
Author
Collaborator

Fixed by PR #182 (fix/171-phone-queue-scrim) — CI green, chromium
and webkit.

Took the issue's second direction: below 600px the scrim is not drawn at
all, rather than drawn as a dismissal target with no reachable pixels.
The gutter was declined and the reason is written into CLAUDE.md — it
buys "tap past it" by taking width off a full-screen surface on a 424px
viewport, and #55 already made this a screen whose ways out are back
and a 44x44 close button.

Existence is matchMedia, not display: none (job-band's rule: a
hidden scrim is still an element carrying the handler). The 600-899 band
is untouched and still closes on the scrim — verified at 700x600: host
644x472, panel 320x472, scrim 644x472.

The new e2e case asserts absence at 424x439 rather than clicking,
which is the trap this issue named: a naive phone-width case clicks the
scrim's centre, hits the panel, and passes on the broken build. Both new
tests were watched failing on the pre-fix build.

Not merged — leaving that and Status/In Progress for a human.

Fixed by PR #182 (`fix/171-phone-queue-scrim`) — **CI green**, chromium and webkit. Took the issue's second direction: below 600px the scrim is not drawn at all, rather than drawn as a dismissal target with no reachable pixels. The gutter was declined and the reason is written into `CLAUDE.md` — it buys "tap past it" by taking width off a full-screen surface on a 424px viewport, and #55 already made this a *screen* whose ways out are back and a 44x44 close button. Existence is `matchMedia`, not `display: none` (`job-band`'s rule: a hidden scrim is still an element carrying the handler). The 600-899 band is untouched and still closes on the scrim — verified at 700x600: host 644x472, panel 320x472, scrim 644x472. The new e2e case asserts **absence** at 424x439 rather than clicking, which is the trap this issue named: a naive phone-width case clicks the scrim's centre, hits the panel, and passes on the broken build. Both new tests were watched failing on the pre-fix build. Not merged — leaving that and `Status/In Progress` for a human.
logan closed this issue 2026-08-21 16:47:46 +00:00
gitea-actions bot removed the
Status
In Progress
label 2026-08-21 16:47:56 +00:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: yonlu/yellowjacket#171