How Mobile Chromium Handles Viewports and Address Bars

This article explains how the Chromium browser on mobile platforms interprets viewport meta tags and manages the dynamic hiding of the address bar during vertical page scrolling. It breaks down the relationship between the layout and visual viewports, details how Chromium prevents performance degradation when screen real estate changes, and outlines the modern CSS viewport units used to manage these dynamic resize events.

Interpreting the Viewport Meta Tag

When a mobile Chromium browser loads a webpage, its rendering engine (Blink) immediately scans the document head for the <meta name="viewport"> tag.

Without this tag, Chromium assumes the webpage is designed for desktop monitors. It renders the page inside a fallback layout viewport—typically 980 pixels wide—and scales the result down to fit the narrow mobile screen, forcing the user to pinch-to-zoom to read text.

When developers include <meta name="viewport" content="width=device-width, initial-scale=1">, Chromium alters its rendering pipeline:

  • Width Calculation: It sets the layout width to match the device's screen width in Device Independent Pixels (DIPs) rather than physical hardware pixels.
  • Scale Initialization: It establishes a 1:1 relationship between CSS pixels and DIPs, preventing the default zoomed-out view and ensuring media queries trigger at the correct mobile breakpoints.

Layout Viewport vs. Visual Viewport

To handle touch scrolling, zooming, and dynamic UI elements smoothly, Chromium divides the concept of the "screen" into two distinct viewports:

  1. The Visual Viewport: This is the physical portion of the webpage the user currently sees on their screen. If the user pinch-zooms in, or if the on-screen keyboard pops up, the visual viewport shrinks.
  2. The Layout Viewport: This is the unseen coordinate space Chromium uses to calculate CSS geometry, such as elements styled with width: 100%, height: 100vh, or position: fixed.

Dynamic Address Bar Hiding During Scrolling

On mobile devices, vertical screen space is limited. To maximize the reading area, Chromium hides its top address bar (and bottom toolbar, if present) when the user scrolls down the page. When the user scrolls back up, the browser UI reappears.

This behavior creates a complex rendering challenge. As the address bar retracts, the visible area of the screen grows taller by roughly 56 pixels (depending on the device). If Chromium updated the Layout Viewport on every single frame of the address bar's retraction animation, the browser would have to recalculate the size and position of every percentage-based element on the page 60 times per second. On mobile processors, this continuous recalculation—known as "layout thrashing"—causes severe frame drops and jittery scrolling.

How Chromium Prevents Layout Shifts

To ensure 60-frames-per-second (or 120fps) scrolling performance, Chromium decouples standard CSS viewport height (vh) units from the real-time movement of the address bar.

Chromium manages the vertical scroll and address bar retraction through the following mechanics:

  • Static 100vh Sizing: Chromium locks the definition of 100vh to the largest possible viewport height—the state where the address bar is completely hidden.
  • Initial Load Overflow: Because 100vh equals the screen height without the address bar, an element set to height: 100vh will actually be taller than the visible screen when the page first loads (since the address bar is initially visible). The bottom of that element will be pushed slightly below the screen fold.
  • Compositor-Driven Fixed Elements: For elements anchored to the bottom of the screen (e.g., position: fixed; bottom: 0;), Chromium uses its compositor thread (GPU) to shift these elements down in real-time as the address bar hides. This visually keeps the element glued to the bottom of the screen without triggering an expensive CSS layout recalculation on the main CPU thread.
  • Resize Event Delay: Chromium waits until the user lifts their finger from the screen, or until the address bar completely finishes its retraction animation, before firing the JavaScript window.onresize event and updating the internal layout geometry.

Modern CSS Viewport Units in Chromium

Locking 100vh to the hidden-address-bar state solved scrolling performance issues, but it frustrated developers whose full-screen layouts were cut off on initial page load. To resolve this, Chromium implemented three specific viewport units that account for the dynamic address bar:

  • Small Viewport Height (svh): Represents the viewport height when the address bar is fully visible. Setting an element to 100svh guarantees it will fit strictly within the visible screen on initial page load without overflowing.
  • Large Viewport Height (lvh): Represents the viewport height when the address bar is completely hidden. This acts identically to Chromium's standard vh unit.
  • Dynamic Viewport Height (dvh): Dynamically shifts between the svh and lvh values depending on whether the address bar is currently shown or hidden. To preserve scrolling performance, dvh does not animate smoothly on every frame; instead, it snaps to the new height once the address bar finishes its transition.