R4.05.2visual viewportdesign

Mobile browsers have distinctive viewport and keyboard behavior

Aliases: layout viewport · visual viewport · virtual keyboard · 100vh

What it is

In a desktop browser the window is roughly the viewport. Mobile browsers split that idea in two. The layout viewport is the sheet CSS uses to lay out the document. The visual viewport is the window the user currently sees, reshaped by pinch-zoom and by the IME (virtual keyboard). When the address bar rises or falls, or the keyboard slides up, the visual viewport shrinks; the layout viewport may not follow. 100vh often includes the strip covered by browser chrome. A position: fixed bottom bar may float, get pushed up, or sit behind the keyboard—three engines, three outcomes.

This is why “the screen” is not a usable word in mobile browsers, not the general widget forks between spec and implementation. Pinning a bottom bar the way desktop fixed positioning works assumes there is only one viewport.

Why it happens

The layout viewport stays relatively stable so the document does not reflow on every pinch. The visual viewport tracks the user’s observation window so the magnified region can be seen. The keyboard is a third occupant: some engines shrink the visual viewport so a fixed bar rises above the keys; some overlay the keyboard on the layout viewport, leaving the bar at the document bottom and actually invisible; some change window.innerHeight only while an input is focused. IMEs also have a candidate bar. Chinese and Japanese composition eat another strip of height, and a 26-key English layout is not the same height as a nine-key Chinese layout.

The address bar showing and hiding rewrites visual height as a side effect of scroll direction, not as an API the page can call. “The bottom of the screen” therefore has at least three candidates: layout-viewport bottom, visual-viewport bottom, and the top of the keyboard. A design that honors only one of them will drop the critical button onto the other two during input. Pinch-zoom turns the visual viewport into a small rectangle inside the layout viewport; fixed elements stay pinned to the layout viewport and the user sees them slide out of the current window.

Where it stops holding

On desktop and on tablets with a hardware keyboard the IME does not occupy the viewport; the problem collapses to window resize and docked devtools, and the three-viewport model is unnecessary. In-app WebViews may negotiate a different keyboard policy than the system browser; Safari or Chrome behavior is not a fact inside the shell. A fullscreen wrapper that hides the address bar still raises the system IME, but it loses the address-bar layer. Landscape, split view, and folding change both viewports’ initial values; a bar tuned only on a tall narrow portrait will misplace again when rotated.

Applying it

  • Pin primary actions to the visual viewport or to the top of the keyboard, not to 100vh as “the height I can see.” A form submit must remain tappable or scrollable into view while the IME is open.
  • Distinguish “bottom of the document” from “bottom of what I see now.” A reading toolbar may follow the layout viewport; Send / Next during input must follow the visual viewport.
  • Inspect fixed and sticky elements with the Chinese candidate bar open, with the address bar expanded, and under pinch-zoom.
  • Verify in the system browser: focus an input near the bottom, type with a Chinese IME, and watch whether submit, error text, and a custom tab bar are covered by the keyboard or candidate bar, hover over the candidates, or jump with the address bar. Repeat in three engines. Any pass that needs two taps to hit submit pinned the bar to the wrong viewport.

Related

  • Same group: R4.05.1 Specified behavior and implemented behavior diverge · R4.05.3 Progressive enhancement is the basic strategy for divergence
  • Adjacent: C6.06 Soft keyboard and screen occupancy · C6.12 IME candidates
  • Search terms: visual viewport · layout viewport · virtual keyboard · IME

Cards in the same group

Quick Actions

Share

Share this page

ios_share

https://hci.top/en/handbook/R4.05.2