Handling Content Obstruction with the Virtual Keyboard API

Devices like tablets and smartphones typically have virtual keyboards for text input. Unlike physical keyboards, which are always present and consistent, the appearance and disappearance of virtual keyboards depend on user actions or attribute changes, such as the inputmode attribute.

This flexibility means the browser’s layout engine must know whether the virtual keyboard is visible and may need to adjust the document layout. For example, an input field clicked by the user may be covered by the virtual keyboard, so the browser must scroll the page to keep the input field in view.

Usually, browsers respond to the virtual keyboard by:

  1. Repositioning content above the virtual keyboard
  2. Reducing the viewport height to avoid obstruction
  3. Shrinking the visual viewport and filling the layout viewport to ensure content moves above the keyboard

The Virtual Keyboard API allows browsers to keep the layout and viewport unchanged, and provides information about the virtual keyboard and viewport, enabling developers to customize page layouts via JavaScript or CSS environment variables.

The Virtual Keyboard API consists of three parts:

  1. The VirtualKeyboard interface on the navigator object, for controlling the virtual keyboard via JavaScript
  2. CSS environment variables, providing information about the virtual keyboard’s appearance
  3. The virtual keyboard policy, which determines whether the keyboard should be shown

Browser Support Detection

The following code snippet detects whether the current browser supports the VirtualKeyboard API:

if ('virtualKeyboard' in navigator) {
  // The VirtualKeyboard API is supported!
}

Using the VirtualKeyboard API

The VirtualKeyboard API adds a new interface, VirtualKeyboard, to the navigator object.

Using the New Virtual Keyboard

To tell the browser you want to handle virtual keyboard obstruction yourself, set the overlaysContent property to true:

navigator.virtualKeyboard.overlaysContent = true;

Showing and Hiding the Virtual Keyboard

You can show the virtual keyboard by calling the show() method. The focused element must be a form control (such as a textarea) or an editable element (for example, with the contenteditable attribute). This method always returns undefined and triggers the geometrychanged event.

navigator.virtualKeyboard.show();

To hide the virtual keyboard, call the hide() method. This method also always returns undefined and triggers the geometrychanged event.

navigator.virtualKeyboard.hide();

geometrychanged Event

Whenever the virtual keyboard appears or disappears, the geometrychanged event is triggered. The event’s target property contains a DOMRect object with the new virtual keyboard information.

navigator.virtualKeyboard.addEventListener('geometrychanged', (event) => {
  const { x, y, width, height } = event.target;
  console.log('Virtual keyboard geometry changed:', x, y, width, height);
});

Getting the Current Geometry

You can get the current geometry of the virtual keyboard by checking the boundingRect property, which exposes the current size as a DOMRect object.

const { x, y, width, height } = navigator.virtualKeyboard.boundingRect;
console.log('Virtual keyboard geometry:', x, y, width, height);

CSS Environment Variables

The VirtualKeyboard API provides a set of CSS environment variables that give information about the virtual keyboard’s appearance, similar to the inset CSS property, corresponding to top, right, bottom, and/or left.

  • keyboard-inset-top
  • keyboard-inset-right
  • keyboard-inset-bottom
  • keyboard-inset-left
  • keyboard-inset-width
  • keyboard-inset-height

These environment variables define the distance from the virtual keyboard to the edges of the visual viewport.

You can use these environment variables as shown in the following examples:

.some-class {
  /**
   * Use a margin that corresponds to the virtual keyboard's height
   * if the virtual keyboard is shown, else use the fallback value of `50px`.
   */
  margin-block-end: env(keyboard-inset-height, 50px);
}

.some-other-class {
  /**
   * Use a margin that corresponds to the virtual keyboard's height
   * if the virtual keyboard is shown, else use the default fallback value of `0px`.
   */
  margin-block-end: env(keyboard-inset-height);
}

Virtual Keyboard Policy

The virtualkeyboardpolicy attribute controls whether the virtual keyboard appears automatically. Allowed values are auto and manual.

<!-- The virtual keyboard appears only on double-click -->
<div
  contenteditable
  virtualkeyboardpolicy="manual"
  inputmode="text"
  ondblclick="navigator.virtualKeyboard.show();"
>
  Double-click to edit.
</div>

References

© 2025 Yihao.dev. All rights reserved.