Virtual Keyboard Api
The virtual keyboard has always been a blind spot for web layout. An API that tells you where it sits on screen -- and CSS environment variables to respond to it -- exists in Chrome. Apple is not there yet.
Any mobile web developer who has built a chat interface knows the problem. And unlike touch and pointer events -- which are universally supported -- the API that solves this problem is Chrome-only for now.
User taps the message input. The virtual keyboard slides up. It either covers the input box completely, or the browser resizes the viewport and everything jumps. Neither is what you want. What you want is to know exactly how much space the keyboard is taking and adjust your layout to match.
That is what the Virtual Keyboard API does.
What the API Provides
Three things:
- Opt out of automatic viewport resize. Tell the browser that you will handle the keyboard layout yourself.
- A
geometrychangeevent. Fires when the keyboard appears, disappears, or changes size. The event carries aboundingRectwith the keyboard'sx,y,width, andheightin screen coordinates. - CSS environment variables. A set of
keyboard-inset-*values you can reference in CSS without writing any JavaScript.
How to Use It
First, opt out of automatic behavior:
if ('virtualKeyboard' in navigator) {
navigator.virtualKeyboard.overlaysContent = true
}Without this line, the browser resizes the viewport when the keyboard appears -- the old default behavior. Setting overlaysContent = true turns that off. The keyboard overlays your content and you handle it.
Then listen for geometry changes:
navigator.virtualKeyboard.addEventListener('geometrychange', (event) => {
const { x, y, width, height } = event.target.boundingRect
// height is 0 when keyboard is hidden, non-zero when visible
document.body.style.setProperty('--kb-height', `${height}px`)
})Or skip the JavaScript entirely and use CSS:
.chat-input-bar {
padding-bottom: env(keyboard-inset-height, 0px);
}env(keyboard-inset-height, 0px) is zero when the keyboard is hidden, and jumps to the keyboard's height when it appears. The input bar moves up automatically without a single line of JavaScript.
ExpandVirtual Keyboard API: opt in, listen for geometrychange, adapt layout with CSS env variables
The Chat UI Pattern
This API was created specifically because the chat/messaging layout is notoriously hard to get right on mobile.
Without the API, common symptoms: the message input bar goes behind the keyboard, the scroll position jumps when the keyboard opens, or the entire conversation thread resizes awkwardly.
With the API, the flow is:
- Set
overlaysContent = truewhen the page loads. - Apply
padding-bottom: env(keyboard-inset-height, 0px)to the scrollable conversation area. - When the keyboard opens, the conversation shrinks from the bottom. The input stays visible. No jumps.
Where It Works
Chrome on Android and Chrome on Windows (for detachable tablets where the hardware keyboard can be unplugged). Chromium generally from version 94.
Apple has not shipped this API. It is not in Safari on iOS or macOS. It falls into the light-green tier -- Chromium only. Feature detection with 'virtualKeyboard' in navigator is required. The page should work without it -- just with the older auto-resize behavior.
const supportsVKB = 'virtualKeyboard' in navigator
if (supportsVKB) {
navigator.virtualKeyboard.overlaysContent = true
// precise control
} else {
// browser handles resize automatically -- less precise but functional
}The virtual keyboard is an OS-managed input surface. The next input category is completely different: external hardware the browser exposes through a standardized interface. That is the Gamepad API -- and the first thing to know is that it does not use events.
The Essentials
- The Virtual Keyboard API solves the chat UI problem: knowing where the keyboard sits so you can adjust layout precisely.
- Opt in with
navigator.virtualKeyboard.overlaysContent = true. Without this, the API does nothing. - Use
geometrychangefor JavaScript-side layout. Useenv(keyboard-inset-height)for pure CSS. - Chrome only. Apple not implementing yet. Always feature-detect before using.
boundingRect.height === 0means keyboard is hidden. Non-zero means visible and the value tells you exactly how tall.
Further Reading and Watching
- Full Control with the VirtualKeyboard API -- Chrome for Developers -- official documentation with the chat UI demo and live examples
- The Virtual Keyboard API -- Ahmad Shadeed -- detailed breakdown of the CSS environment variables and layout patterns
Keep reading