Make hidden mean hidden, and check that it does

Three rounds inside the money, so this one was a look at the thing. On a desktop
screenshot of a table mid-session there is a small empty box under the bank
check: 21 pixels wide, 44 tall, no text, no purpose. It is the "Take $600 from 3
players" button from three rounds ago, which sets `hidden` when there is nothing
to record — and `hidden` was losing.

The attribute carries its `display: none` from the browser's own stylesheet,
which is the weakest rule in the cascade, so any class that sets a display beats
it. Every button class here sets `inline-flex`. This is not a new discovery in
this file either: seven overlays already carry their own `[hidden] { display:
none }`, each one presumably found the same way. One global rule now covers all
of them, so there is no ninth.

The audit had been telling me. Its touch check reported the box as "could not be
probed (drawn 21x44)" — in the warnings, which my sweeps printed only sometimes
and never failed on. So the check now says the plainer thing: an element that
claims to be hidden and is drawn anyway is a fault, not a note. It is in runAll
with the rest, and the bug was put back by hand to confirm it fires.

The same warning stream had a second thing in it: the waiting list's Add button
was 43px wide. Three letters, one pixel under the rule, and a thumb doesn't know
the word is short.

182 audits across 13 viewports, both input kinds, every overlay and a table with
a rake, a cash-out, a waiting list and six logged hands on it: clean, and the
only note left is the one that says the 44px rule stood itself down on a mouse.

Co-Authored-By: Claude Opus 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_015bnp7xKUPFFSpwkYNFaPgb
This commit is contained in:
2026-09-02 09:36:51 -06:00
co-authored by Claude Opus 5
parent 4db6f6e4d3
commit 8616636212
2 changed files with 38 additions and 0 deletions
@@ -318,6 +318,20 @@ button,
margin-top: 1rem;
}
/* `hidden` means hidden.
The attribute only carries `display: none` from the browser's own stylesheet, which
is the weakest rule there is: any class that sets a display — and every button here
sets `inline-flex` — beats it. That is not a hypothetical. Seven overlays in this
file already carry their own `[hidden] { display: none }` because each one was found
the hard way, and the eighth was a button that shipped as a 21x44 empty box under the
bank check on every table that didn't need it.
One rule, for everything, so there is no ninth. */
[hidden] {
display: none !important;
}
/* ---------- Poker table ---------- */
#pokerTableWrap {
@@ -2338,6 +2352,9 @@ body.hasActionBar #holdemSidebar {
.waitingAdd .holdemBtn {
flex: none;
min-height: 44px;
/* "Add" is three letters, which came out 43px wide — one pixel under the rule, and
the audit called it. A thumb doesn't know the word is short. */
min-width: 56px;
}
.waitingList {
+21
View File
@@ -719,6 +719,26 @@ const LayoutAudit = {
return { name: "the felt shows one dealer button", offenders };
},
// Anything that says it is hidden and is drawn anyway.
//
// `hidden` gets its `display: none` from the browser's own stylesheet, the weakest
// rule in the cascade, so any class that sets a display beats it — and in this tool
// every button class does. The result is an element the code believes is gone,
// sitting on the screen: found as a 21x44 empty box under the bank check, and this
// file's own touch check had been calling it "could not be probed" rather than
// saying the plainer thing, which is that it should not be there at all.
hiddenButPainted() {
const offenders = [...document.querySelectorAll("[hidden]")]
.filter(el => {
const rect = el.getBoundingClientRect();
if (rect.width === 0 || rect.height === 0) return false;
const style = getComputedStyle(el);
return style.display !== "none" && style.visibility !== "hidden";
})
.map(el => `${this.describe(el)} :: hidden, but drawn ${Math.round(el.getBoundingClientRect().width)}x${Math.round(el.getBoundingClientRect().height)}`);
return { name: "hidden means hidden", offenders };
},
// ---- Runner ----
// Every check this file knows how to make, every time.
@@ -747,6 +767,7 @@ const LayoutAudit = {
this.fieldFontSize(),
this.seatOwnership(),
this.oneDealerButton(),
this.hiddenButPainted(),
this.contrast(options.contrast),
this.touchTargets(options.minimumTarget, options.touchTargets),
];