Skip to content

fix(zoom): correctly size fullscreen graph panels on Safari under html{zoom} (#70)#92

Merged
BorisTyshkevich merged 1 commit into
mainfrom
feat/zoom-guard-70
Jun 30, 2026
Merged

fix(zoom): correctly size fullscreen graph panels on Safari under html{zoom} (#70)#92
BorisTyshkevich merged 1 commit into
mainfrom
feat/zoom-guard-70

Conversation

@BorisTyshkevich

@BorisTyshkevich BorisTyshkevich commented Jun 30, 2026

Copy link
Copy Markdown
Collaborator

What & why

The whole UI rides on html { zoom: var(--zoom) }. The pointer/caret/drag math self-calibrates to the live getBoundingClientRect/offsetWidth ratio (the zoom factor on Chromium, 1 on WebKit/Safari), so it was already correct on every engine. The genuine divergence is viewport units under zoom: Chromium's vw/vh ignore it (100vh overshoots one screen by the zoom factor) while WebKit/Safari's track it (100vh == one screen). The fullscreen schema / EXPLAIN graph panels size off vw/vh and hard-coded calc(.../var(--zoom)), which shrank them to ~83% on Safari.

Per the two-step plan in #68 / the issue comment, this is step 1 (the 1.0 fix); step 2 (full zoom removal) stays folded into the Phase 3/5 coordinate-path rewrites (#21/#66).

The fix

  • Runtime measurementapp.applyViewportZoom() measures the real overshoot (a 100vh probe vs the one-screen #root) and publishes it as --vp-zoom (~--zoom on Chromium, ~1 on Safari). The three fullscreen panels divide their vw/vh by --vp-zoom, so they fit exactly one screen on both engines. Pure viewportZoom() in src/core/zoom-support.js (100% covered); the DOM measurement is an injected seam; the opener mirrors --vp-zoom onto the schema graph's child tab.
  • CSS--vp-zoom defaults to var(--zoom) (Chromium-correct) when unmeasurable, so behaviour never regresses; @supports not (zoom: 1) still neutralizes the factor on engines that can't parse zoom at all.
  • Expand icon (src/ui/icons.js) — re-centred + symmetric so it renders consistently at ~12px instead of blurring into solid [ ] brackets on Chrome/Firefox (a pre-existing cosmetic bug surfaced during manual Safari testing; folded in here as it's the Expand button that opens these panels).

This supersedes the earlier abandoned "mis-scaling banner" approach: the rect ratio can't tell a working Safari (ratio 1.0) from a broken engine, so that guard false-positived on Safari — the very engine #70 targeted.

Verification

  • Local unit gate green (1028 tests; zoom-support.js 100/100/100/100), build clean.
  • Chromium (agent Chrome): divisor 1.2, panel fits with just the 48px padding gap; icon clean.
  • Real Safari (manual): the fullscreen panels now fit one screen ✅ (bug + fix confirmed by the maintainer).
  • tests/e2e/zoom-support.spec.js guards the panel-fit mechanism on all three CI engines. Caveat: Playwright's WebKit applies zoom to getBoundingClientRect/viewport units like Chromium, not like real Safari, so it is not a faithful Safari proxy for this behaviour — the real-Safari path is verified manually (tracked in the Document the supported-browser matrix (browsers, ClickHouse versions, IdP requirements) #71 matrix).

Acceptance (issue #70)

  • Confirmed correct on the support matrix (Safari panel sizing fixed + manually verified; Chromium/Firefox unaffected) and a feature-guard/fallback is in place (--vp-zoom + @supports).
  • No silent wrong-scale state on an engine that doesn't honor zoom (CSS 1× fallback for parse-failure; runtime-measured divisor for the viewport-unit divergence).
  • npm test + e2e green; per-file coverage gate holds.

Checklist

🤖 Generated with Claude Code

@BorisTyshkevich BorisTyshkevich mentioned this pull request Jun 30, 2026
23 tasks
…l{zoom} (#70)

The whole UI rides on `html { zoom: var(--zoom) }`. The pointer/caret/drag math
self-calibrates to the live getBoundingClientRect/offsetWidth ratio (the zoom
factor on Chromium, 1 on WebKit/Safari), so it was already correct on every
engine. The one genuine divergence is viewport units under `zoom`: Chromium's
vw/vh ignore it (100vh overshoots one screen by the zoom factor) while
WebKit/Safari's track it (100vh == one screen). The fullscreen schema / EXPLAIN
graph panels size off vw/vh and hard-coded `calc(.../var(--zoom))`, which shrank
them to ~83% on Safari.

Fix: measure the actual overshoot at runtime (a 100vh probe vs the one-screen
#root) and publish it as --vp-zoom (~--zoom on Chromium, ~1 on Safari); the panels
divide by --vp-zoom, so they fit exactly one screen on both. --vp-zoom defaults to
var(--zoom) (Chromium-correct) when unmeasurable, and the opener mirrors it onto
the schema graph's child tab. A `@supports not (zoom: 1)` rule still neutralizes
the factor on engines that can't parse `zoom` at all.

- src/core/zoom-support.js: pure viewportZoom(vhPx, refPx) (100% covered).
- src/ui/app.js: app.applyViewportZoom() measures + publishes --vp-zoom via an
  injected measurement seam; run from renderApp.
- src/ui/explain-graph.js: mirrorTheme carries --vp-zoom onto the child tab.
- src/styles.css: --vp-zoom default + the three panels divide by it.
- src/ui/icons.js: centred + symmetric expand glyph so it renders consistently
  across engines at ~12px (it previously blurred into solid brackets on
  Chrome/Firefox while staying crisp on Safari).
- e2e: tests/e2e/zoom-support.spec.js asserts the panel-fit mechanism on all
  three engines. NOTE: Playwright WebKit applies zoom to rects like Chromium, not
  like real Safari, so the real-Safari path is verified manually (#71).

Supersedes the abandoned boot-time "mis-scaling banner" approach: the rect ratio
can't distinguish a working Safari (ratio 1.0) from a broken engine, so that guard
false-positived on Safari — the very engine #70 targeted.

Closes #70. Part of #68 (Phase 0 release-blocker).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01P5JoqoESpfq4cFibmQX18C
@BorisTyshkevich BorisTyshkevich changed the title feat(zoom): de-risk the html{zoom} layout dependency — feature-guard + loud fallback (#70) fix(zoom): correctly size fullscreen graph panels on Safari under html{zoom} (#70) Jun 30, 2026
@BorisTyshkevich BorisTyshkevich merged commit 4bd9aeb into main Jun 30, 2026
6 checks passed
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