inputmode
Controls which virtual keyboard layout is shown (text, numeric, tel, email, url, search, decimal).
virtualkeyboardpolicy AttributeThe 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.
<element virtualkeyboardpolicy="auto | manual">Content</element>| Value | Description |
|---|---|
auto | Default behavior. The virtual keyboard overlays the viewport, and the browser automatically scrolls to keep the focused element visible. |
manual | The viewport is not affected by the virtual keyboard. The application is responsible for handling layout adjustments using the VirtualKeyboard API. |
manualUse 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.
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.
| Browser | virtualkeyboardpolicy | VirtualKeyboard API |
|---|---|---|
| Chrome | 94+ | 94+ |
| Edge | 94+ | 94+ |
| Safari | No | No |
| Firefox | No | No |
| Chrome Android | 94+ | 94+ |
| Safari iOS | No | No |
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:
inputmodeUse 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).