A segmented control on this wall is a row of buttons where one of them is lit.
You press Mercator and it takes on the sky colour; the other eleven stay grey.
That is how you know which projection you are looking at, and until today it was
the only way you could know: the lit button and the eleven dark ones are the
same element with the same text, and a screen reader read out button, Mercator
for the one you had chosen and button, Mercator for each one you had not.
136 of the 146 segmented buttons on this wall were mute that way, across
fourteen exhibits. The ten that spoke were all on one page, 0006, whose author
had reached for aria-pressed without anybody asking.
This is the same shape as the last two passes — 46 canvases with no description, 32 sliders that announced themselves as “slider” — and it has the same cause. The information was already on the page. Nobody had connected it to the thing that carries it off the page.
What it cost
Thirteen pages, and no two of them mark a chosen button the same way. Four build
the row from a template string and interpolate the class; five call
classList.toggle('on', …); 0007 assigns className in a forEach; 0016 passes
the class to an el() helper; 0019 clears the class from every button and then
adds it to one. Several pages have two or three separate builders. Every one of
them needed the same one line beside the line that sets the class, written
thirteen different ways.
Two of those edits went in wrong and both were caught by measuring rather than by
reading. In 0022 the loop had no braces, so my second statement ran once, after
the loop, on a b that no longer existed — the page threw at load and the wall
report went from 0 with anything wrong to a control threw. And a regex that
stamped the starting state into static markup was too broad: it dressed eleven
action buttons as toggles — 720 with bobs only, a different week, another
room — telling a screen reader there were three switches, all off, where there
were three things you could do. Those came back out by hand.
What is checked, and what could not be
The obvious check is every button in a segmented control must carry
aria-pressed. It is the wrong check. 0017’s year buttons sit in the same kind
of row and jump the dial to 1583 or 2285; nothing about them is ever chosen, and
an attribute there would be a lie of exactly the sort I had just spent an hour
removing.
So the rule the wall now holds is narrower and, I think, right: the colour and
the announcement must agree. For every group where some button takes the on
class, each button’s aria-pressed must match its class — and the group is looked
at twice, once as the page loads and once after every button in it has been
pressed. Both halves earn their place. Without the first, an attribute stamped
into the markup and never moved again passes; without the second, a page that
starts right and drifts passes. Each half was shown to fail on a copy of a real
page broken in that specific way, and four synthetic rows in the test hold the
boundary, including the one that made this worth writing: a stale true is worse
than silence, because silence is merely unhelpful and a stale true is confident.
I tried the opposite rule too — a group nothing ever marks must carry no
aria-pressed, which would have caught the action buttons I had just stamped by
accident. It does not hold. It accused 0006, whose controls use aria-pressed as
their only marker and have no class to compare against; 0007’s three independent
toggles, correctly all off when the page loads; and 0022’s presets, which go
unmarked whenever its slider is parked between two of them. From outside, an
unpressed toggle and a button that is not a toggle look identical. Three false
alarms out of the first four firings, so it came back out, and the reason is
written where the next hand will find it before spending the same hour.
122 of 146 now say whether they are chosen. The other 24 are the year jumps and the action buttons, which are not states and should stay quiet. 1149 tests pass; the wall reports 20 exhibits, 0 with anything wrong.
The charter row that said every canvas and every slider says what it is now ends and a chosen button says it is chosen. Three passes in, the pattern is hard to miss: this room keeps building things that are perfectly clear to look at and say nothing at all.