概要
スマホでテキスト入力欄などをタップしたとき、キーボードが表示されますが、これを「仮想キーボード」または「バーチャルキーボード」(以降「VK」と呼称)と呼びます。
VKの表示 / 非表示のタイミングを検知し、特定の処理を行いたい場面があったのですが、ネット上の記事が最新ブラウザで動かない対応が多く見られましたので、記事に残しておきます。
実際の要件
下部固定メニューをVKの表示時には非表示、VKの非表示時には表示したい
(コンテンツの表示領域が狭くなって邪魔なので)
実際に対応できた一例
window.visualViewportオブジェクトを使って判定します。
具体的には以下のように VKを表示したときの visualViewport(VK分だけ縮んだコンテンツ領域の高さ)と document.documentElement.contentHeight (VKに関係しないコンテンツ領域の高さ)を比較する
<br /><template>
<TheNavigation v-show="isShown" />
</template>
<script setup lang="ts">
// ...
// バーチャルキーボードの表示時はナビを非表示
const isShown = ref(false);
const contentHeight = ref<number>(0);
const offset = 10
const resizeHandler = async () => {
if (visualViewport && visualViewport.height < contentHeight.value - offset) {
isShown.value = false;
} else {
isShown.value = true;
}
};
onMounted(() => {
// AndroidだとVKの表示時にその分windowが縮むので初期表示の高さを取得しておく
// ※ スマホの回転も考えると不十分。こちらも監視する必要あり
contentHeight.value = document.documentElement.contentHeight;
if (visualViewport) {
// resizeイベントをセット
visualViewport.addEventListener('resize', resizeHandler);
}
});
onBeforeUnmount(() => {
if (visualViewport) {
// resizeイベントを削除
visualViewport.removeEventListener('resize', resizeHandler);
}
});
window.visualViewportオブジェクトについて
https://developer.mozilla.org/ja/docs/Web/API/Window/visualViewport
visualViewportを利用すれば以下のようなことが可能です。
- スクリーンキーボードを除いた表示範囲の幅や高さを取得する
- スクリーンキーボードに隠れた範囲のスクロール量を取得する
ブラウザの互換性は概ねモダンブラウザなら問題ありません(2026/1/14現在)

採用を見送った他の方法
ちなみに(検討してみたがダメだった)他の方法も記しておきます。
1. input要素へのフォーカスイベントをキーボードの表示とみなす
2. windowのリサイズをキーボードの表示とみなす
3. windowのスクロール量を監視する
4. interactive-widget をメタタグで設定する
5. VirtualKeyboard APIを用いる(唯一の希望)
1. input要素へのフォーカスイベントをキーボードの表示とみなす
問題点
- 本当に「input 要素にフォーカスされたとき = VKが表示されている」とみなして良いか?という疑問が残る
- キーボードの高さに応じてページの表示を調整するといった処理が不可能
2. ウィンドウのリサイズをキーボードの表示とみなす
Chrome が v108 にアップデートされた辺りで Android 版でのキーボード周りの仕様に以下のような変更がありました。
| 以前の Chrome, Firefox | VK が表示されている間、webページはウインドウサイズがキーボードの高さの分だけ縮められたものとして扱われる |
| Chrome 108 以降、Firefox 132 以降 | キーボードはウインドウの上に重なって表示された扱いとなりビジュアルビューポートのサイズのみが変更される。さらに、フォーカスのあたっているインプットUIの位置へ勝手にスクロールされる |
問題点
- clientHeight などを監視してウインドウのリサイズをキーボードの表示とみなす手法は、前述した旧バージョンのChromeの仕様に依存していて今はそのまま使えない
3. windowのスクロール量を監視する
問題点
- VK に隠れた範囲のスクロールはページのスクロールとはみなさない仕様があるらしく、window.scrollY を監視しても検出できませんでした。
4. interactive-widget をメタタグで設定する
Chrome 108 から HTMLのメタタグに新しい設定値 interactive-widget が追加されました。これにより、VK 表示時に「画面をリサイズするか(resizes-content)」「画面に被せるか(overlays-content)」を制御できるようになりました。
<meta name="viewport" content="width=device-width, initial-scale=1.0, interactive-widget=overlays-content">
これが使えたら、overlays-content を設定するだけでも今回の要件を満たせそうです。
問題点
- 現状 2026年1月14日 現在、
interactive-widget = overlays-contentの指定が Safari では非対応となっています。
5. VirtualKeyboard API を用いる(唯一の希望)
現状、スクリーンキーボードの表示を直接検知するような方法は存在しないようです…。
ですが、VirtualKeyboard API なるAPIを使えば将来的には可能になる可能性があります。
https://developer.mozilla.org/en-US/docs/Web/API/VirtualKeyboard_API
VirtualKeyboard APIを使えば、VKの挙動設定(VKをコンテンツに被せるか縮めるか)や形状などを自由に取得できます。
例えば、今回の要件は以下の対応でできるようになるのではないでしょうか?今後に期待です!
if ("virtualKeyboard" in navigator) {
// VKはコンテンツに被せるように表示する
navigator.virtualKeyboard.overlaysContent = true;
}
問題点
- 現状 2026年1月14日 現在、Safari, Firefox では非対応となっています。
備考: ChromeでのVK表示時のデバッグについて
スクリーンキーボード表示時の動作のデバッグですが、現行のデスクトップ版Chromeの開発者ツールにはスクリーンキーボードの表示をエミュレートする機能はなく、デバッグ作業は全て実機か仮想マシンで行うしかないようです。(https://www.kakun.jp/web/20230102/)
表示/非表示と同時になにか処理を行う場合のデバッグは難しそうです。
ただ、表示時にどういったUIになるのかのデバッグはできないことはないかもしれません。
① DevToolsを開いてスマホ表示に切り替え、左上の機種名のプルダウンから「Edit」を選択

② Settingsページの「Devices」の項目から Nexus系統のスマホにチェック

③ 表示をNexus系統のスマホに切り替えた状態で右上の「スマホを回転するマーク」を選択するとプルダウンが出るので、「Portrait – keyboard」を選択
