Skip to content

fix: a wide table made the whole page scroll sideways on a phone - #123

Merged
fas89 merged 1 commit into
mainfrom
fix/table-overflow
Sep 14, 2026
Merged

fas89 merged 1 commit into
mainfrom
fix/table-overflow

Conversation

@fas89

@fas89 fas89 commented Sep 14, 2026

Copy link
Copy Markdown
Collaborator

Found by looking at the rendered site in a browser, not at the HTML.

concepts/sovereignty.html carries a three-column comparison of the two sovereignty gates. At a 357px viewport it renders at its natural 595px, pushing the document to 619px — so the entire page scrolls horizontally, the classic mobile failure where body text drifts under your thumb as you scroll.

before after
document scrollWidth @ 357px 619 357
page scrolls horizontally yes no
wide table overflows the page 309px box, 595px content, scrolls internally

Why it was only this page

Code blocks never had the problem: the theme gives pre an overflow-x: auto, which is why a 798px bash line sits happily inside a 307px column. Tables had no equivalent containment anywhere in the site. cli/validate.html is clean only because its widest table happens to fit.

So the fix is global rather than a tweak to one table: any table in the page body now scrolls inside its own box. display: block is what makes overflow-x apply at all — a display: table box ignores it — and width: fit-content keeps narrow tables at their natural size instead of stretching them to the column.

Two measurement traps, recorded because both nearly gave the wrong answer

getBoundingClientRect on clipped content reports the full width, not the visible width. Sorting elements by their right edge pointed straight at a code block sitting inside an already-scrollable pre — innocent. The guilty table was further down the list. The honest query is "widest element with no scrollable ancestor".

Reading a computed transform immediately after setting it returns the pre-transition value. That made the new skip link look as though it never revealed on focus — twice. It works: transition: transform .15s, and after settling it moves from -46px to 0 and back. No defect; my instrument was simply faster than the animation.

Also verified in the browser while there

  • Light mode: zero contrast failures across hero, cards, body, links and sidebar — ratios 5.17 to 18.93 against a 4.5 requirement
  • Both new hero cards render and read as intended
  • The 0.15.0 release banner replaced the stale 0.12.0 block

Found by looking at the rendered site rather than the HTML.

`concepts/sovereignty.html` carries a three-column comparison of the two
sovereignty gates. At a 357px viewport it renders at its natural 595px, pushing
the document to 619px, so the ENTIRE PAGE scrolls horizontally - the classic
mobile failure where body text drifts under your thumb.

Code blocks never had this problem: the theme gives `pre` an `overflow-x: auto`,
which is why a 798px bash line sits happily inside a 307px column. Tables had no
equivalent, so nothing contained them. `cli/validate.html` is clean only because
its widest table happens to fit.

So the fix is global rather than a tweak to my table: any table in the page body
now scrolls inside its own box. `display: block` is what makes `overflow-x`
apply at all - a `display: table` box ignores it - and `width: fit-content`
keeps narrow tables at their natural size instead of stretching them.

Verified at 357px: document scrollWidth was 619 against a 357 viewport, and is
now 357 with no horizontal page scroll; the wide table reports a 309px box with
595px of content and scrolls internally.

Two measurement traps worth recording, because both nearly produced a wrong
answer:

`getBoundingClientRect` on clipped content reports the FULL width, not the
visible width. Sorting elements by their right edge therefore pointed at a code
block inside an already-scrollable `pre` - innocent - while the guilty table sat
further down the list. The honest query is "widest element with no scrollable
ancestor".

And reading a computed `transform` immediately after setting it returns the
pre-transition value. That made the skip link look as though it never revealed
on focus. It does: `transition: transform .15s`, and after settling it moves
from -46px to 0. No defect - my instrument was too fast.
@fas89
fas89 merged commit 98a9a3a into main Sep 14, 2026
2 checks passed

This branch was successfully deployed

1 active deployment
github-pages — ce11d79f Deployed Sep 14, 2026 by fas89 via deploy #154
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant