目次
- はじめに:100vhを使ったらスマホで高さがズレた
- 100vhとは何か(まずここを整理)
- 100vh問題とは何か(スニペット向け定義)
- なぜスマホでズレるのか
- スマホブラウザの特殊仕様
- 問題の核心
- よくある実務トラブル
- ファーストビューが微妙にズレる
- 横スクロール問題とセットで起きる
- DevToolsで確認する方法
- 手順
- 応急処置:min-heightを使う
- 根本解決:dvhを使う
- 100dvh
- svh・lvhとの違い
- 100svh
- 100lvh
- フォールバック対応(安全な書き方)
- JavaScript対応はまだ必要?
- 100vhを使わないほうがいいケース
- よくある失敗例
- チェックリスト
- どう考えればいいか
- まとめ:100vhは便利。でもスマホでは注意
はじめに:100vhを使ったらスマホで高さがズレた
ヒーローエリアを画面いっぱいにしたくて、こう書いたことありませんか?
.section {
height: 100vh;
}
PCではきれいに表示される。
でもスマホで見ると、
- 下に変な余白ができる
- 少しだけスクロールできてしまう
- 画面ぴったりのはずがはみ出している
「え、なんで?」となります。
実はこれ、CSSのミスではなくスマホ特有の仕様が原因です。
私も最初にLPを作ったとき、ファーストビューが微妙にズレていて、CSSを何時間も疑い続けました。原因は100vhでした。
ここから、仕組みをちゃんと整理します。
100vhとは何か(まずここを整理)
100vh = ビューポートの高さ100%
vhは「viewport height」の略で、
- 1vh = 画面の高さの1%
という意味です。
height: 100vh;
は「画面いっぱいの高さにする」という指定です。
PCでは問題ありません。
問題はスマホです。
100vh問題とは何か(スニペット向け定義)
100vh問題とは、スマホブラウザのアドレスバー表示仕様によって、height:100vh が実際の表示領域とズレてしまう現象のことです。
ここがポイントです。
なぜスマホでズレるのか
スマホブラウザの特殊仕様
スマホには、
- 上部のアドレスバー
- 下部のツールバー
があります。
しかもこれ、スクロールすると「消えたり戻ったり」します。
問題の核心
100vhは「最大表示時の高さ」で計算されることがあります。
つまり、
- アドレスバーが消えた状態の高さを基準にする
- 実際に見えている高さとは違う
だから、
- 下に余白ができる
- 微妙にスクロールできる
- ヒーローがはみ出す
という現象が起きます。
よくある実務トラブル
ファーストビューが微妙にズレる
.hero {
height: 100vh;
}
PC:完璧
スマホ:少しスクロールできる
これ、LP制作あるあるです。
横スクロール問題とセットで起きる
100vhズレ + overflow制御ミス
→ 画面が揺れる
→ スマホ崩れに見える
実務ではこのパターンも多いです。
DevToolsで確認する方法
「本当に100vhが原因?」と思ったら、確認します。
手順
- Chromeでスマホ表示モードにする
- Elementsタブを開く
- 対象要素を選択
- Computedタブでheightのpx値を見る
実際の表示領域とpx値がズレていれば、100vh問題の可能性が高いです。
さらに、
- window.innerHeight
- document.documentElement.clientHeight
をConsoleで確認すると差が見えます。
応急処置:min-heightを使う
まず試せるのがこれ。
.hero {
min-height: 100vh;
}
高さ固定ではなく「最低高さ」にすることで、
不自然なはみ出しを防ぎやすくなります。
ただし、根本解決ではありません。
根本解決:dvhを使う
最近のブラウザでは、新しい単位が使えます。
100dvh
.hero {
height: 100dvh;
}
dvhは「dynamic viewport height」。
つまり、今見えている高さに追従する単位です。
アドレスバーが出ても消えても、
現在の高さで再計算されます。
これが一番安定します。
svh・lvhとの違い
100svh
最小高さ(バー表示状態基準)
100lvh
最大高さ(バー非表示基準)
基本は100dvhでOKです。
フォールバック対応(安全な書き方)
.hero {
min-height: 100vh;
min-height: 100dvh;
}
対応ブラウザではdvhが優先されます。
JavaScript対応はまだ必要?
昔はこれをよく使いました。
const vh = window.innerHeight * 0.01;
document.documentElement.style.setProperty('--vh', `${vh}px`);
.hero {
height: calc(var(--vh) * 100);
}
今は基本不要です。
dvhが使えるならCSSだけで十分です。
100vhを使わないほうがいいケース
- テキスト量が多い
- 可変コンテンツ
- ブログ記事ページ
- フォーム画面
こういう場合は固定高さよりも、
padding + min-height
のほうが安定します。
よくある失敗例
- 100vhをそのままコピペする
- PCだけで確認して公開する
- overflow:hiddenで無理やり隠す
これ、あとで必ず直すことになります。
チェックリスト
✔ スマホ実機で確認したか
✔ DevToolsでheightの実数値を見たか
✔ 100vhをそのまま使っていないか
✔ dvhに置き換えられないか
✔ min-heightで対応できないか
どう考えればいいか
覚えておくのはこれだけ。
- PCとスマホは別物
- 100vhはスマホでズレることがある
- 迷ったら100dvh
これで大半のトラブルは回避できます。
まとめ:100vhは便利。でもスマホでは注意
100vhは悪い指定ではありません。
ただ、スマホの仕様と相性が悪い場面があります。
これからは、
- height:100vh → まず疑う
- min-heightを検討
- 可能なら100dvh
この意識を持つだけで、
スマホ崩れ・余白問題・スクロール違和感はかなり減ります。
ファーストビューで悩んだら、まず100vhを確認。
ここからチェックしてみてください。