You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Web dashboard: rollup tiles associate their number and label by reading-order proximity only, with no programmatic relationship #3031
The web dashboard's fleet rollup tiles associate each number with its label by reading-order proximity only — no programmatic relationship. It is a page-wide property of the .rollup num/label pattern, not a property of any one tile, which is why it is filed here rather than fixed inside the PR that surfaced it.
Measured, not inferred
Against fc7e3f09fb (#3027), on the Deadlocks (recent) tile and its new coverage sub-line:
The sub-line text is in the accessibility tree — generic "read 0 of 12 servers" — and in the correct reading order. Flat browse order reads … "0", "Deadlocks (recent)", "read 0 of 12 servers". It is not hover-only and not unavailable.
Meaning is carried by text, not colour. The yellow is redundant, so there is no WCAG 1.4.1 failure.
role=null, aria-label=null, aria-describedby=null, tabIndex=-1. Association is proximity alone — arguably a 1.3.1 concern, and arguably only because the reading order happens to be right.
Why this is page-wide rather than one tile's problem
The Blocking tile beside it associates its own 0 with its label by the identical proximity-only pattern. Every .rollup tile does. So a fix applied to one tile would make that tile the odd one out and leave the pattern intact everywhere else — which is the argument for doing it once, at the helper, rather than at a call site.
Worth stating plainly: #3027 did not lower the page's bar. It added a sub-line that follows the existing convention. This issue is about the convention.
One residual that is genuinely hover-only, and is a different shape
The rendered coverage note — 169 characters, on title of a non-interactive div — is sighted-only. It is absent from the accessibility tree as a description, and a title on a non-interactive element is not reliably announced.
That is the real availability gap, as distinct from the association gap above.
Shape of a fix
A stable id on the sub-line plus aria-describedby on the number, giving "0, read 0 of 12 servers". Applied at the tile helper so every rollup tile inherits it rather than one.
Do not attach the long note to aria-describedby. 169 characters announced on every pass over the number is worse than the hover-only status quo — the short coverage fact is the right accessible carrier, and the note is not. That call was made deliberately when the sub-line was built and should not be reversed by someone tidying up.
Not verified
Light mode and high-contrast rendering were not tested. The accessibility-tree readings above were taken against a stubbed/api/fleet, not a live Darling service — the field names were cross-checked against real serializer output, but no end-to-end request was made. No assistive technology was driven; the tree was read programmatically rather than with a screen reader.
Provenance note, because it matters for how this is read
An earlier summary of this finding — mine — described the coverage figure as "available rather than visible," implying it was missing from the accessibility tree. That was wrong, and in the direction that wastes a reviewer's time: someone hunting an availability failure on the figure will not find one. The lane that raised it measured its own claim and corrected it downward, which is how the narrower and accurate version above exists.
Closed by #3038, merged to dev at b17e69a820e62a12365ab2679dbade01a432bf73. Closing by hand because a closing keyword does not fire against dev.
The rollup tile now carries its coverage on the tile itself rather than in an adjacent sub-line. Measured rather than assumed: six of the seven tiles have no sub-line at all, so the id + aria-describedby shape this issue originally sketched would have fixed exactly one of them and left the other six describing nothing. That measurement is why the fix is page-wide.
One thing this does not cover, and it is the same defect one page over.ag.js's rollup() carries the identical proximity-only num/lbl pattern — a number and its label associated by adjacency in the DOM rather than by a programmatic reference, which is what made the original tile unreadable to a screen reader. util.js's hoist is the shape the fix should take there. Filing separately rather than widening this one, because the two pages' tile builders do not share a code path and a single PR touching both would be reviewed as two changes wearing one number.
One correction to what I wrote above: I described the fix as "the util.js hoist is the shape." There is no util.js hoist — rollupTextId and the wired tile closure both live in fleet.js, and nothing in util.js exposes a tile or id helper. So #3045 is not "call the existing shared helper"; creating one is the decision it carries. #3045 states both options and why the hoist is probably right.
Activity
Tie each fleet rollup tile's number to its label and coverage sub-line (
erikdarlingdata commentedon Sep 5, 2026
Claude posting for Erik Darling
Closed by #3038, merged to
devatb17e69a820e62a12365ab2679dbade01a432bf73. Closing by hand because a closing keyword does not fire againstdev.The rollup tile now carries its coverage on the tile itself rather than in an adjacent sub-line. Measured rather than assumed: six of the seven tiles have no sub-line at all, so the
id+aria-describedbyshape this issue originally sketched would have fixed exactly one of them and left the other six describing nothing. That measurement is why the fix is page-wide.One thing this does not cover, and it is the same defect one page over.
ag.js'srollup()carries the identical proximity-onlynum/lblpattern — a number and its label associated by adjacency in the DOM rather than by a programmatic reference, which is what made the original tile unreadable to a screen reader.util.js's hoist is the shape the fix should take there. Filing separately rather than widening this one, because the two pages' tile builders do not share a code path and a single PR touching both would be reviewed as two changes wearing one number.erikdarlingdata commentedon Sep 5, 2026
Claude posting for Erik Darling
Follow-up filed as #3045.
One correction to what I wrote above: I described the fix as "the
util.jshoist is the shape." There is noutil.jshoist —rollupTextIdand the wired tile closure both live infleet.js, and nothing inutil.jsexposes a tile or id helper. So #3045 is not "call the existing shared helper"; creating one is the decision it carries. #3045 states both options and why the hoist is probably right.Tie the AG rollup's numbers to their labels, from a shared id helper (#…
Wire the sweep tiles' figures to their labels, and stop the page's pr…
Render the sweep's memory: the Fleet Sweeps page (#3466, lane 3 of 4) (…