Skip to content

fix(html): fitting the width states a floor a wide page can reach - #911

Merged
andiwand merged 2 commits into
mainfrom
fix/fit-width-states-a-floor
Sep 20, 2026
Merged

andiwand merged 2 commits into
mainfrom
fix/fit-width-states-a-floor

Conversation

@andiwand

@andiwand andiwand commented Sep 20, 2026

Copy link
Copy Markdown
Member

A browser floors the page scale at 0.25. width=device-width alone leaves that floor in place, so content more than four screens wide cannot be zoomed out to: it opens at its own size, scrolls sideways, and the pinch stops before the page fits.

Measured in OpenDocument Reader's WebView on an A0-sized pdf page - 3232 css px on a 412 px screen: visualViewport.scale sat at 0.25 with less than half the page visible, and no gesture could go lower.

Fitting the width now states the floor the content needs: what it takes to fit the widest page on a 320 px screen, the narrowest there is. Where 0.25 already reaches - every ordinary page - nothing is added and the meta is unchanged, so no existing output moves.

content before after
A4 portrait (794px) width=device-width,user-scalable=yes unchanged
A4 landscape (1122px) unchanged unchanged
A0 landscape (3232px) unchanged …,minimum-scale=0.099,…
text document, spreadsheet …,initial-scale=1.0,… unchanged (they do not fit the width)

write_viewport_meta takes the content_pixels that write_zoom_style beside it already takes; the call sites without one state no floor, as before.

Checked

  • odr_test --gtest_filter=html*: 98 tests, all passing, including a new one that the floor appears only when the page column is wider than four screens.
  • Rendered by hand with cli/translate: the A0 page gains minimum-scale=0.099; an A4 landscape menu, a normal pdf, five presentations, an odt and two spreadsheets are byte-identical.
  • On a device, the same meta (set by hand through viewport_content) makes the A0 page open fitted, with both edges on screen.

A browser floors the page scale at 0.25, so `width=device-width` alone
cannot fit content more than four screens wide: an A0 sheet on a phone
opens at its own size, scrolls sideways, and the pinch stops before the
page fits. Measured in a WebView at 3232 css px on a 412 px screen, the
scale sat at 0.25 with less than half the page visible.

Fitting the width now states the floor the content needs - what fits the
widest page on a 320 px screen, the narrowest there is. Where the
browser's own 0.25 already reaches, nothing is added and the meta is
unchanged, so no existing output moves.

`write_viewport_meta` takes the `content_pixels` that `write_zoom_style`
beside it already takes. The call sites without one state no floor.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FJJdfqpnVCKBNHXjAVxSou
@andiwand
andiwand force-pushed the fix/fit-width-states-a-floor branch from 97139a7 to 548f80d Compare September 20, 2026 09:46
`viewport_of` sat outside the anonymous namespace, so it had external
linkage where `fit_of` beside it does not. The assertions now state the whole
meta, which catches the order of the clauses and the separators.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0149gFxhkvKTBQidz6brU8Vt
@andiwand
andiwand merged commit c7a60a8 into main Sep 20, 2026
23 checks passed
@andiwand
andiwand deleted the fix/fit-width-states-a-floor branch September 20, 2026 09:52
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