スマホ用レイアウトでは、お問い合わせボタンなどを画面の最下部に固定して配置することがよくあります。片手で操作していても親指で押しやすく、常に目に入るので便利です。
ところが、フォーム入力時にiPhoneでバーチャルキーボードが下からせり上がってくると、最下部に固定したボタンもそれに合わせてせり上がり、入力欄を隠してしまうことがあります。結論から言うと、入力欄にフォーカスした瞬間に<body>へクラスを付け、そのクラスが付いている間だけ固定要素をCSSで非表示にすることで解決できます。

上の画像のように、キーボードとともにせり上がった固定ボタンが入力欄にかぶってしまいます。見づらいだけでなく、フォーム入力時に誤ってボタンを押し、別ページに遷移してしまうこともあります。そこで、キーボードが立ち上がっている間は、最下部に固定したボタン類を非表示にしたい——というのが今回のゴールです。
バーチャルキーボードの表示・非表示を直接検知するのは難しいのですが、入力欄(input・textarea)にフォーカスが当たるタイミング=キーボードが立ち上がるタイミングとみなせます。そこで、フォーカス時に<body>へクラスを追加し、フォーカスが外れたら削除します。
$("input, textarea").focus(function () {
$(document.body).addClass('keyboard-active');
});
$("input, textarea").blur(function () {
$(document.body).removeClass('keyboard-active');
});
あとは、keyboard-activeクラスが付いている間だけ、最下部固定要素(ここでは.contact)を非表示にするCSSを書くだけです。
.keyboard-active .contact {
display: none;
}
これで、キーボードが立ち上がっている間だけ固定ボタンが消え、入力欄がボタンに隠れることも、誤タップで遷移してしまうこともなくなります。
なお、jQueryを使わない場合は、addEventListener('focus', ...)とaddEventListener('blur', ...)で同じことができます。focusin/focusoutを使えば、親要素でまとめてフォーカスの出入りを拾えるので、入力欄が多いフォームでも扱いやすくなります。
この方法は、フォーカスの有無でキーボードの状態を推測するシンプルな手法です。そのため、入力欄から別の入力欄へ移るときに一瞬blur→focusが続き、固定要素がちらつくことがあります。気になる場合は、非表示ではなく透明度や位置をずらす方法にしたり、少し遅延を入れたりといった調整も検討できます。
より厳密にキーボードやビューポートの変化を扱いたい場合は、visualViewportAPIで表示領域の高さの変化を監視する方法もあります。まずは今回のシンプルな方法で試し、要件に応じて精度を上げていくとよいでしょう。
input・textareaのフォーカスで<body>にクラスを付け外しするスマホのフォームは、ちょっとした表示の重なりが入力のストレスにつながります。最下部固定のボタンを置くときは、キーボード表示時の見え方まで気を配ると、フォームの完成度がぐっと上がります。