useVisualViewport
useVisualViewport is a React hook that tracks Visual Viewport changes. It returns the actual visible area in mobile WebView, which changes when the keyboard appears or the user zooms/scrolls.
Interface
function useVisualViewport(): { viewport: VisualViewportState | null };Parameters
This function does not accept any parameters.
Return Value
- { viewport: VisualViewportState | null }
An object containing the Visual Viewport state.
- viewportVisualViewportState | null
Visual Viewport state object, or
nullif not supported (SSR or browsers without the Visual Viewport API). - viewport.widthnumber
Viewport width in pixels.
- viewport.heightnumber
Viewport height in pixels.
- viewport.offsetLeftnumber
Viewport left offset in pixels from the layout viewport. Typically 0 unless horizontal scrolling or panning occurs.
- viewport.offsetTopnumber
Viewport top offset in pixels from the layout viewport. Becomes negative on iOS when the keyboard appears (e.g., -300px means a 300px keyboard), so use
-offsetTopfor the keyboard height. Typically remains 0 on Android. - viewport.scalenumber
Pinch-zoom scaling factor. 1.0 means no zoom, greater than 1.0 means zoomed in, and less than 1.0 means zoomed out (rare, depends on viewport settings).
- viewportVisualViewportState | null
Example
function CustomLayout() {
const { viewport } = useVisualViewport();
// Always check for null first
if (!viewport) {
return <div>Visual Viewport not supported</div>;
}
const { width, height, offsetTop, scale } = viewport;
// Hide floating UI when user zooms in
const showFloatingUI = scale <= 1.3;
return (
<div style={{ height }}>
{showFloatingUI && <FloatingButton />}
Viewport-aware content
</div>
);
}Detecting zoom
const { viewport } = useVisualViewport();
if (viewport && viewport.scale > 1.3) {
// Hide floating UI when user zooms in
setShowFloatingButton(false);
}Notes
- SSR safety:
viewportisnullduring server-side rendering and in browsers without the Visual Viewport API. Always check fornullbefore reading its properties. - Browser support: The Visual Viewport API is supported in modern mobile browsers. Where it is missing the hook returns
null. - Performance: Updates are wrapped in React's
startTransitionso viewport changes do not block urgent rendering. - Simpler alternative: If you only need the keyboard height, use
useKeyboardHeight()for a simpler API. - Platform differences: On iOS
offsetTopbecomes negative when the keyboard appears; on Android it typically stays at 0. - Use cases: Detecting the keyboard, reacting to pinch-zoom gestures, building viewport-aware layouts, and showing or hiding UI by zoom level.