なぜ100vhがはみ出すのか
vh(viewport height)は画面の高さの1%を表す単位ですが、モバイルブラウザでは1vhがアドレスバーを含んだ「最大の高さ」を基準に計算されることがあります。
ところがアドレスバーが表示されている初期状態では、実際に見えている領域はそれより小さくなります。結果、100vhの要素は実表示領域より大きくなり、下端がアドレスバーの裏に隠れたり、はみ出してスクロールが出たりします。
さらにスクロールに応じてアドレスバーが伸縮するため、表示領域の高さが動的に変わります。これがレイアウトのガタつきや見切れを引き起こします。
dvh・svh・lvhの使い分け
この問題に対応するため、ビューポートの状態を区別した単位が用意されています。svh(small)はアドレスバーが表示された状態の小さい高さ、lvh(large)はアドレスバーが隠れた大きい高さ、dvh(dynamic)はその時々の実表示領域に追従する高さです。
画面いっぱいに見せたいヒーローセクションなどでは、はみ出しを避けたいなら svh を、常に実表示にぴったり合わせたいなら dvh を使うのが基本です。dvhはアドレスバーの伸縮に追従するため自然ですが、追従の過程で高さが変わる点は理解しておきましょう。
lvhは最大高さを基準にするため、アドレスバー表示時にははみ出します。全面に敷くには不向きで、用途を選んで使います。
症状別チェック表
iOSで100vhがアドレスバー分はみ出すは、症状を分けずに直そうとすると原因探しが長引きます。まず「自分だけで起きるのか」「全員で起きるのか」「特定ブラウザだけか」「差し替え後だけか」を切り分けます。
確認順序を固定すると、相対パス、ファイル名、キャッシュ、認証、外部読み込みのどこで止まっているかが見えます。修正後はローカル確認だけで終わらせず、実際の共有URLで再表示して、相手と同じ条件で直ったことを確認します。
- 自分だけ表示されない: キャッシュ、ログイン状態、ブラウザ拡張、端末幅を確認する
- 全員で表示されない: ファイル構成、相対パス、大文字小文字、アップロード漏れを見る
- 一部だけ崩れる: CSS/画像/JSごとに読み込みエラーを分ける
- 差し替え後だけ古い: URL、キャッシュ、更新対象ファイルの取り違えを確認する
対処の手順
古い環境へのフォールバックも考えつつ、次の順で適用すると安全です。
- まず height: 100vh をフォールバックとして残す
- その直後に height: 100dvh(または 100svh)を上書きで指定する
- ヒーローやモーダルなど全画面要素ではみ出しを避けたいなら svh を選ぶ
- アドレスバーに追従させたいなら dvh を選ぶ
- 実機のSafari/Chromeで、スクロール時のガタつきと下端の見切れを確認する
JavaScriptを使う従来の回避策
dvhなどに対応していない古い環境を強くサポートする必要がある場合は、JavaScriptで実際の window.innerHeight を取得し、CSS変数に1%分の高さを書き込む手法が以前から使われてきました。
ただしこの方法はリサイズやアドレスバーの伸縮ごとに再計算が必要で、コードも増えます。現在の主要ブラウザはdvh系の単位に対応しているため、まずはdvh/svhで試し、足りない部分だけJSで補うのが現実的です。
新規制作であれば、最初からdvh/svhを前提に組み、100vhはフォールバックとして併記しておくと保守が楽になります。
実機で挙動を確認する
vhの問題はアドレスバーの伸縮が絡むため、PCのブラウザでは再現しにくく、iOSの実機Safariで確認するのが確実です。スクロールしながら下端の挙動を見るのがポイントです。
ギガサイト便なら修正版のHTML/ZIPをドロップして共有URLを発行し、手元のiPhoneですぐ確認できます。CDNのエッジ配信で表示が速く、実機での体感も本番に近い形で見られます。
同じURLのままファイルを差し替えられるので、svhとdvhを切り替えて試す比較作業もスムーズです。確認をチームに頼むときはQRコードを配布すると素早く共有できます。
よくある質問
svhとdvhはどちらを使えばいいですか
アドレスバー表示時でもはみ出させたくない全画面要素にはsvhが安全です。アドレスバーの伸縮に高さを追従させて常に実表示にフィットさせたい場合はdvhを使います。用途で選び分けてください。
古いブラウザでdvhが効きません
先に height: 100vh をフォールバックとして書き、その後 height: 100dvh を上書き指定します。dvh非対応環境では100vhが、対応環境ではdvhが適用されます。どうしても厳密に合わせたい場合のみJSで補います。
dvhにするとスクロール中に高さがガタつきます
dvhはアドレスバーの伸縮に追従するため、その過程で高さが変化します。ガタつきを避けたい場合はsvhを使うか、固定したい部分だけ別単位にするなど用途で切り分けてください。
Android Chromeでも同じ問題は起きますか
Android Chromeでもアドレスバーの伸縮でviewport高さが変わるため、同様の見切れが起きることがあります。dvh/svhはマルチプラットフォームで使えるので、両方の実機で確認するのが確実です。
原因が分からないときはどこから確認すべきですか?
まず自分だけの問題か全員の問題かを分けます。次にシークレットウィンドウ、別ブラウザ、スマホで確認し、ファイル構成・相対パス・キャッシュ・認証設定を順に見ます。