Skip to content

Web dashboard: rollup tiles associate their number and label by reading-order proximity only, with no programmatic relationship #3031

Description

@erikdarlingdata

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.

Activity

  1. erikdarlingdata commented on Sep 5, 2026

    @erikdarlingdata
    OwnerAuthor

    Claude posting for Erik Darling

    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.

  2. erikdarlingdata commented on Sep 5, 2026

    @erikdarlingdata
    OwnerAuthor

    Claude posting for Erik Darling

    Follow-up filed as #3045.

    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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions