Skip to content

virtualkeyboardpolicy - Virtual Keyboard Behavior

Global Attribute HTML Living Standard

The virtualkeyboardpolicy attribute controls how the browser handles the virtual keyboard (on-screen keyboard) on mobile devices when an editable element receives focus. It determines whether the virtual keyboard overlays the viewport or whether the application takes manual control of layout adjustments.

Result
<element virtualkeyboardpolicy="auto | manual">Content</element>
ValueDescription
autoDefault behavior. The virtual keyboard overlays the viewport, and the browser automatically scrolls to keep the focused element visible.
manualThe viewport is not affected by the virtual keyboard. The application is responsible for handling layout adjustments using the VirtualKeyboard API.

Use virtualkeyboardpolicy="manual" when your application needs:

Fixed or Floating UI Elements

When you have elements positioned at the bottom of the viewport that should remain visible above the keyboard rather than being pushed up or hidden.

Custom Scroll Behavior

When you want to control exactly how the page scrolls when the keyboard appears, rather than relying on the browser’s default behavior.

Bottom Navigation Bars

When you have a fixed navigation bar at the bottom that should adjust its position when the keyboard is visible.

Full-Screen or Immersive Experiences

When building applications that need precise control over the viewport, such as games, drawing apps, or custom editors.

Result
Result
Result

When using virtualkeyboardpolicy="manual", you should integrate with the VirtualKeyboard API to detect when the keyboard is shown or hidden and adjust your layout accordingly.

<input
type="text"
virtualkeyboardpolicy="manual"
id="chat-input"
>
<script>
if ('virtualKeyboard' in navigator) {
// Allow the virtual keyboard to overlay content
navigator.virtualKeyboard.overlaysContent = true;
// Listen for geometry changes
navigator.virtualKeyboard.addEventListener('geometrychange', (event) => {
const { x, y, width, height } = navigator.virtualKeyboard.boundingRect;
// Adjust layout based on keyboard dimensions
if (height > 0) {
// Keyboard is visible
document.getElementById('chat-input').style.bottom = `${height}px`;
} else {
// Keyboard is hidden
document.getElementById('chat-input').style.bottom = '0';
}
});
}
</script>
if ('virtualKeyboard' in navigator) {
navigator.virtualKeyboard.addEventListener('geometrychange', () => {
const keyboardHeight = navigator.virtualKeyboard.boundingRect.height;
const isKeyboardVisible = keyboardHeight > 0;
if (isKeyboardVisible) {
console.log(`Keyboard shown: ${keyboardHeight}px tall`);
// Adjust UI for keyboard
} else {
console.log('Keyboard hidden');
// Reset UI
}
});
}
if ('virtualKeyboard' in navigator) {
const input = document.getElementById('my-input');
// Show the virtual keyboard
input.focus();
// Hide the virtual keyboard
navigator.virtualKeyboard.hide();
// Show the virtual keyboard
navigator.virtualKeyboard.show();
}

The virtualkeyboardpolicy attribute and VirtualKeyboard API have limited browser support, primarily in Chromium-based browsers.

BrowservirtualkeyboardpolicyVirtualKeyboard API
Chrome94+94+
Edge94+94+
SafariNoNo
FirefoxNoNo
Chrome Android94+94+
Safari iOSNoNo

Since browser support is limited, implement progressive enhancement with feature detection:

<input type="text" id="message-input">
<script>
const input = document.getElementById('message-input');
// Check for VirtualKeyboard API support
if ('virtualKeyboard' in navigator) {
// Use manual policy with API
input.setAttribute('virtualkeyboardpolicy', 'manual');
navigator.virtualKeyboard.overlaysContent = true;
navigator.virtualKeyboard.addEventListener('geometrychange', () => {
// Handle keyboard changes
adjustLayout();
});
} else {
// Fallback: rely on browser default behavior
// Use CSS-only solutions like position: fixed
console.log('VirtualKeyboard API not supported, using fallback');
}
</script>
/* Fallback for browsers without VirtualKeyboard API */
.input-container {
position: fixed;
bottom: 0;
left: 0;
right: 0;
padding: 12px;
background: white;
border-top: 1px solid #ddd;
}
/* Use environment variables for safe area insets on iOS */
.input-container {
padding-bottom: calc(12px + env(safe-area-inset-bottom));
}
<!-- Help mobile browsers with viewport behavior -->
<meta
name="viewport"
content="width=device-width, initial-scale=1, interactive-widget=resizes-content"
>

Always pair virtualkeyboardpolicy="manual" with the VirtualKeyboard API to properly handle layout adjustments:

if ('virtualKeyboard' in navigator) {
navigator.virtualKeyboard.overlaysContent = true;
navigator.virtualKeyboard.addEventListener('geometrychange', () => {
const keyboardHeight = navigator.virtualKeyboard.boundingRect.height;
document.querySelector('.fixed-footer').style.bottom = `${keyboardHeight}px`;
});
}

Ensure your application works without the feature:

<!-- Works with and without VirtualKeyboard API -->
<div class="chat-container">
<div class="messages"></div>
<div class="input-wrapper">
<input type="text" virtualkeyboardpolicy="manual">
</div>
</div>
<style>
/* Fallback positioning */
.input-wrapper {
position: sticky;
bottom: 0;
background: white;
}
</style>

Virtual keyboard behavior varies significantly across devices. Always test on:

  • Android devices with different keyboard apps
  • iOS devices (where the feature isn’t supported yet)
  • Tablets with different screen sizes
  • Devices in both portrait and landscape orientations

Use with the inputmode attribute to provide the most appropriate keyboard layout:

<input
type="text"
virtualkeyboardpolicy="manual"
inputmode="numeric"
placeholder="Enter PIN"
>

When using virtualkeyboardpolicy="manual", ensure that:

Focus Remains Visible

When the keyboard appears, make sure the focused input remains visible and not obscured by other UI elements.

navigator.virtualKeyboard.addEventListener('geometrychange', () => {
const focusedElement = document.activeElement;
if (focusedElement) {
focusedElement.scrollIntoView({ behavior: 'smooth', block: 'center' });
}
});

Keyboard Navigation Works

Ensure users can navigate between form fields using the keyboard’s next/done buttons.

Screen Reader Compatibility

Test with screen readers to ensure the manual keyboard handling doesn’t interfere with assistive technology.

inputmode

Controls which virtual keyboard layout is shown (text, numeric, tel, email, url, search, decimal).

enterkeyhint

Customizes the label or icon of the Enter key on virtual keyboards (enter, done, go, next, previous, search, send).