yes.js: freeze .hero-yes's height via inline style, don't trust svh alone
Deploy / deploy (push) Successful in 34s

The container-rect approach (reading .hero-canvas's rendered rect via
ResizeObserver) still jumped on the real device: .hero-copy kept
sliding down as the address bar collapsed even with svh (then lvh)
driving .hero-yes's height, meaning the box's actual rendered height
wasn't holding still the way the "stable" viewport units are spec'd
to. Reading a rect only helps if what it reads is actually fixed - it
wasn't, so no amount of matching the canvas to it would help.

yes.js now writes the fix instead of reading around it: it measures
window.innerWidth/innerHeight once and sets that literal px height as
an inline style on the hero element. Inline style beats the
stylesheet's `height: 100svh` in the cascade, so the box's rendered
height becomes a fixed number in the DOM rather than something
recomputed from a viewport unit on every layout - nothing the browser
does with svh afterward can move it. The old width-gated resize
listener comes back to re-freeze on a genuine resize (orientation
change), since that's still the correct signal for "the address-bar
animation is not what's happening right now."
This commit is contained in:
Bendik Aagaard Lynghaug
2026-08-06 21:38:58 +02:00
parent d7f280e681
commit 2422f5fb49
2 changed files with 50 additions and 35 deletions
+10 -10
View File
@@ -153,16 +153,16 @@ main.loading, main.not-found {
position: relative;
max-width: none;
width: 100%;
/* svh (small viewport height): a fixed, stable length - computed
once, never recalculated mid-scroll as mobile Safari's address
bar hides/shows, unlike plain vh/dvh on some engines. Pinned to
the *smallest* possible viewport (toolbar visible) so the box
never needs to grow into space the toolbar might reclaim.
yes.js's canvas measures this box's own rendered rect (not
window.innerWidth/innerHeight) via ResizeObserver, so the canvas
always matches whatever height this resolves to - the two can't
disagree, which is what was actually causing the content below to
visibly jump.
/* svh here is only the pre-JS/no-JS fallback (and first paint before
yes.js's constructor runs). Once yes.js mounts, it overwrites this
with an inline `height: <px>` frozen from a single measurement -
see setupCanvas()'s comment in yes.js for why: on real mobile
Safari, content bottom-aligned inside this box kept sliding down
as the address bar collapsed even with a spec'd-stable viewport
unit here, so the box's actual height can't be trusted to stay
put on that unit alone. An inline style set from JS always wins
the cascade over this rule, so that frozen number is what
actually governs once the page is interactive.
Plain-vh fallback declared first - an engine without svh support
ignores the invalid second line rather than falling through to
auto height, which would collapse this to the height of its