All hooks / Viewport and media

useVisualViewport

285 B minified and brotliedSourceMarkdown✓ Works in all modern browsers

The visual viewport: the part of the page actually visible, which shrinks when the on-screen keyboard opens on phones and moves with pinch zoom.

bottomInset is how many pixels at the bottom of the layout viewport are covered, so a fixed bottom bar can move above the keyboard. Renders serverValue on the server and during hydration. Falls back to the window size where visualViewport is missing.

Import

import { useVisualViewport } from '@vincent.ri/react-tils'
// or only this hook
import { useVisualViewport } from '@vincent.ri/react-tils/useVisualViewport'

Usage

const { bottomInset } = useVisualViewport()
return <form style={{ position: 'fixed', left: 0, right: 0, bottom: bottomInset }}><ChatInput /></form>

Live demo

On a phone, open the keyboard: bottomInset grows.

0×0 · bottomInset 0

When to use it

Keeping a chat input, bottom toolbar, or "Save" bar visible above the mobile keyboard, or positioning UI correctly while pinch-zoomed.

When not to

You just need the window size; use useWindowSize. Where supported, CSS can handle the keyboard: the interactive-widget=resizes-content viewport meta setting, or env(keyboard-inset-height) with the VirtualKeyboard API.

API

function useVisualViewport(serverValue?: VisualViewportState): VisualViewportState
ParameterDescription
serverValueValue on the server and during hydration. Default all zeros, scale 1.

Types

export type VisualViewportState = {
  /** Visible width in CSS pixels. */
  width: number;
  /** Visible height in CSS pixels; shrinks when the on-screen keyboard opens. */
  height: number;
  offsetTop: number;
  offsetLeft: number;
  /** Pinch-zoom scale. */
  scale: number;
  /** How much of the layout viewport's bottom is hidden, usually by the on-screen keyboard. */
  bottomInset: number;
};

Browser support

UsesChromeEdgeFirefoxSafariChrome AndroidSafari iOS
VisualViewportWidely available61+79+91+13+61+13+

First version with support, from MDN's compatibility data (web-features 3.42.0, @mdn/browser-compat-data 8.1.5).