Found by the responsive-layout harness added for #13
(make frontend-viewport-test). This is a real defect in the layout, not a
harness artifact.
Symptom
At a 320px viewport the page scrolls horizontally: documentElement.scrollWidth
is 350 against a 320px layout viewport. Reproduced at every run, only at 320px —
667, 767, 768, 769, 844 and 1280 are clean.
Cause
.status-text in hostRowHTML() (src/main.js) carries whitespace-nowrap,
and once a tick has populated it the content reads e.g. min 167ms / med 167ms / avg 167ms / max 167ms. Measured at 320px that is 325px
of unbreakable text inside a 270px box, and since the element does not clip, the
overflow propagates all the way up to the document:
The max-width: 768px block in src/styles.css sets the info block to width: 100% but never addresses this line, so the narrow layout inherits a
nowrap string sized for the 420px desktop column.
Suggested fix
Allow the status line to wrap (or shorten it) below the breakpoint. Any fix is
fine as long as make frontend-viewport-test reports no-horizontal-overflow
passing at 320x568 — the harness already asserts this and names the offending
element on failure.
Note for whoever picks this up
window.innerWidth is useless for detecting this. Under mobile emulation Chrome
lets innerWidth grow to the width of the overflowing content — it reports 350,
matching the overflow exactly, so a check written as scrollWidth <= innerWidth passes while the page is visibly broken. The
harness compares against Math.min(innerWidth, documentElement.clientWidth)
instead.
Found by the responsive-layout harness added for #13
(`make frontend-viewport-test`). This is a real defect in the layout, not a
harness artifact.
## Symptom
At a 320px viewport the page scrolls horizontally: `documentElement.scrollWidth`
is 350 against a 320px layout viewport. Reproduced at every run, only at 320px —
667, 767, 768, 769, 844 and 1280 are clean.
## Cause
`.status-text` in `hostRowHTML()` (`src/main.js`) carries `whitespace-nowrap`,
and once a tick has populated it the content reads e.g.
`min 167ms / med 167ms / avg 167ms / max 167ms`. Measured at 320px that is 325px
of unbreakable text inside a 270px box, and since the element does not clip, the
overflow propagates all the way up to the document:
```
div.status-text.text-xs | rect 25..295 w270 | scrollWidth 325 / clientWidth 270
| overflow-x: visible white-space: nowrap
```
The `max-width: 768px` block in `src/styles.css` sets the info block to
`width: 100%` but never addresses this line, so the narrow layout inherits a
nowrap string sized for the 420px desktop column.
## Suggested fix
Allow the status line to wrap (or shorten it) below the breakpoint. Any fix is
fine as long as `make frontend-viewport-test` reports `no-horizontal-overflow`
passing at 320x568 — the harness already asserts this and names the offending
element on failure.
## Note for whoever picks this up
`window.innerWidth` is useless for detecting this. Under mobile emulation Chrome
lets `innerWidth` grow to the width of the overflowing content — it reports 350,
matching the overflow exactly, so a check written as
`scrollWidth <= innerWidth` passes while the page is visibly broken. The
harness compares against `Math.min(innerWidth, documentElement.clientWidth)`
instead.
Ref #13, #5, #2
Dropped whitespace-nowrap from .status-text and made each label / value / separator group its own unbreakable span, so the line wraps
only between stats and never begins with a /. At 320px it renders as two
right-aligned rows; in the 420px desktop column it still fits on one row, so
the wide layout is unchanged.
Verified with make frontend-viewport-test in a throwaway clone with #44 merged on top (the harness is not
on next yet, and none of its files are in this branch). At 320x568, no-horizontal-overflow goes FAIL (scrollWidth 350 vs viewport 320) to PASS,
and nothing-past-viewport-edge with it: 5/8 to 7/8 checks. 1280x800 stays
7/7; 769x1024 and 844x390 are unchanged. make check green.
The remaining 320px failure is tap-targets-44px
(#43), untouched here.
Fixed in https://git.eeqj.de/sneak/netwatch/pulls/50 (base `next`).
Dropped `whitespace-nowrap` from `.status-text` and made each
`label / value / separator` group its own unbreakable span, so the line wraps
only between stats and never begins with a `/`. At 320px it renders as two
right-aligned rows; in the 420px desktop column it still fits on one row, so
the wide layout is unchanged.
Verified with `make frontend-viewport-test` in a throwaway clone with
https://git.eeqj.de/sneak/netwatch/pulls/44 merged on top (the harness is not
on `next` yet, and none of its files are in this branch). At 320x568,
`no-horizontal-overflow` goes FAIL (`scrollWidth` 350 vs viewport 320) to PASS,
and `nothing-past-viewport-edge` with it: 5/8 to 7/8 checks. 1280x800 stays
7/7; 769x1024 and 844x390 are unchanged. `make check` green.
The remaining 320px failure is `tap-targets-44px`
(https://git.eeqj.de/sneak/netwatch/issues/43), untouched here.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Found by the responsive-layout harness added for #13
(
make frontend-viewport-test). This is a real defect in the layout, not aharness artifact.
Symptom
At a 320px viewport the page scrolls horizontally:
documentElement.scrollWidthis 350 against a 320px layout viewport. Reproduced at every run, only at 320px —
667, 767, 768, 769, 844 and 1280 are clean.
Cause
.status-textinhostRowHTML()(src/main.js) carrieswhitespace-nowrap,and once a tick has populated it the content reads e.g.
min 167ms / med 167ms / avg 167ms / max 167ms. Measured at 320px that is 325pxof unbreakable text inside a 270px box, and since the element does not clip, the
overflow propagates all the way up to the document:
The
max-width: 768pxblock insrc/styles.csssets the info block towidth: 100%but never addresses this line, so the narrow layout inherits anowrap string sized for the 420px desktop column.
Suggested fix
Allow the status line to wrap (or shorten it) below the breakpoint. Any fix is
fine as long as
make frontend-viewport-testreportsno-horizontal-overflowpassing at 320x568 — the harness already asserts this and names the offending
element on failure.
Note for whoever picks this up
window.innerWidthis useless for detecting this. Under mobile emulation Chromelets
innerWidthgrow to the width of the overflowing content — it reports 350,matching the overflow exactly, so a check written as
scrollWidth <= innerWidthpasses while the page is visibly broken. Theharness compares against
Math.min(innerWidth, documentElement.clientWidth)instead.
Ref #13, #5, #2
Fixed in #50 (base
next).Dropped
whitespace-nowrapfrom.status-textand made eachlabel / value / separatorgroup its own unbreakable span, so the line wrapsonly between stats and never begins with a
/. At 320px it renders as tworight-aligned rows; in the 420px desktop column it still fits on one row, so
the wide layout is unchanged.
Verified with
make frontend-viewport-testin a throwaway clone with#44 merged on top (the harness is not
on
nextyet, and none of its files are in this branch). At 320x568,no-horizontal-overflowgoes FAIL (scrollWidth350 vs viewport 320) to PASS,and
nothing-past-viewport-edgewith it: 5/8 to 7/8 checks. 1280x800 stays7/7; 769x1024 and 844x390 are unchanged.
make checkgreen.The remaining 320px failure is
tap-targets-44px(#43), untouched here.
clawbot referenced this issue2026-09-03 18:21:21 +02:00
clawbot referenced this issue2026-09-04 00:26:59 +02:00
clawbot referenced this issue2026-09-04 00:27:52 +02:00