PR
TIPS

lvh svh dvh の違いと使い分け モバイル表示崩れを防ぐCSS実装手順

スマホサイトで「100vhにしたのに下が切れる」「アドレスバー表示でレイアウトが跳ねる」と困っている方向けに、lvh・svh・dvhの違いと実装手順を整理します。この記事では、単位の意味だけでなく、実務でそのまま使えるCSS例、確認手順、失敗しやすいポイントまでまとめます。

本記事の対象読者

  • モバイルで全画面セクションを作るときに高さが安定しない方
  • 従来の `vh` だけでは挙動を制御しにくいと感じている方
  • WordPressテーマやLPで、ヒーローや固定CTAを安全に実装したい方

vhが起こしやすい問題

モバイルブラウザでは、アドレスバーやツールバーの表示状態によって、実際に見えている領域の高さが変化します。`100vh` はこの変化と一致しないことがあり、表示切れや余白、スクロールジャンプの原因になります。

この問題を解決しやすくするために、CSS Values and Unitsで `svh` `lvh` `dvh` が定義されました。目的は「どの状態のビューポートを基準にするか」を明示できるようにすることです。

lvh svh dvh の基本整理

単位基準向いている用途注意点
svh最小ビューポート高絶対に隠したくないUI余白が多く見える場面があります
lvh最大ビューポート高広い表示領域を優先する画面UI表示時に一部が隠れる可能性があります
dvh動的ビューポート高表示領域変化へ追従したい要素状態変化で再計算が走るため体感揺れが出る場合があります

`1svh` `1lvh` `1dvh` はそれぞれ対応するビューポート高の1%です。単位の意味はシンプルですが、どの画面要素に適用するかで体感が大きく変わります。全要素を `dvh` に置き換えるより、用途ごとの使い分けが重要です。

前提条件

  • レスポンシブ対応のHTMLとCSSがすでにあること
  • 主要ブラウザの最新版で検証できること
  • 古いOSや古いWebViewを対象に含む場合はフォールバックを残すこと

現在の主要ブラウザは `svh` `lvh` `dvh` を概ね扱えますが、実運用では利用者の端末が混在します。既存サイト改修では、いきなり `vh` を全削除せず、`@supports` や複数指定で段階的に移行する構成が安全です。

実装手順

基本フォールバック構成

まずは従来ブラウザでも崩れにくい土台を作ります。用途は「全画面に近い高さを持つセクションのベース設定」です。`vh` を先に置き、対応ブラウザで `svh` または `dvh` を上書きする形にします。

.hero {
  min-height: 100vh;   /* フォールバック */
  min-height: 100svh;  /* UI表示時も隠れにくい */
}

@supports (height: 100dvh) {
  .hero {
    min-height: 100dvh; /* 対応環境では動的追従 */
  }
}

注意点として、`height` を固定するとコンテンツ量によってはみ出しやすくなります。ヒーローやフォームでは `min-height` を基本にして、本文が増えたときの破綻を避ける方が実務的です。

ヒーローセクション適用

ファーストビューで余白バランスを優先するケースです。見た目の安定を優先したい場合は `svh`、アドレスバーの開閉に追従させたい場合は `dvh` を選びます。

.hero {
  display: grid;
  place-items: center;
  padding: 24px;
  min-height: 100svh;
}

.hero--dynamic {
  min-height: 100dvh;
}

LPでアニメーション量が多い場合、`dvh` だとUI表示変化のたびに再レイアウトが目立つことがあります。その場合は `.hero` を `svh` 固定にし、背景だけ別要素で追従させると違和感を減らせます。

固定CTAとフォーム適用

入力フォームや固定CTAでは「隠れないこと」を最優先にします。下部安全領域を含めるため、`env(safe-area-inset-bottom)` の併用が有効です。

.cta-fixed {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  padding: 12px 16px calc(12px + env(safe-area-inset-bottom));
}

.form-screen {
  min-height: 100svh;
  padding-bottom: calc(16px + env(safe-area-inset-bottom));
}

キーボード表示時の挙動はOSやブラウザ実装差の影響を受けます。フォーム画面では `svh` を軸にし、必要な要素だけ `dvh` にする構成の方が予期しないジャンプを抑えやすいです。

動作確認

  1. スマホ実機でページを開き、初期表示で見切れがないか確認します
  2. 上下スクロールしてアドレスバー表示状態を切り替え、ヒーロー高さの変化を確認します
  3. フォームでキーボードを開閉し、入力欄や送信ボタンが隠れないか確認します
  4. 画面回転を行い、縦横それぞれで意図した高さになるか確認します
  5. 古い端末やWebViewで `vh` フォールバックが効いているか確認します

確認時はDevToolsのエミュレーションだけで判断しないのが安全です。UIバーの挙動は実機と差が出ることがあるため、最低でもiOS SafariとAndroid Chromeの実機確認を推奨します。

トラブルシュート

スクロール時の高さ跳ね症状

`dvh` をレイアウト全体に適用すると、UI表示変化で複数要素が同時に再計算され、ガタついて見えることがあります。主要コンテナは `svh` にし、視覚的に追従してほしい一部要素だけ `dvh` に限定すると改善しやすいです。

コンテンツ下端の隠れ症状

固定フッターやホームインジケータにコンテンツが重なる場合は、要素の高さだけでなく内側余白を調整します。`padding-bottom` に `env(safe-area-inset-bottom)` を足すと、端末依存の欠けを減らせます。

古い環境の未対応症状

一部の古い環境では `dvh` が効かないか、期待通りに再計算されない場合があります。`@supports (height: 100dvh)` で分岐し、未対応環境は `vh` または `svh` のまま運用する設計にしておくと安全です。

.panel {
  min-height: 100vh;
}

@supports (height: 100svh) {
  .panel {
    min-height: 100svh;
  }
}

@supports (height: 100dvh) {
  .panel--dynamic {
    min-height: 100dvh;
  }
}

実務での使い分け指針

  • 絶対に隠したくないUIは `svh` を優先します
  • 画面変化に合わせたい要素は `dvh` を局所的に使います
  • 広い表示を優先する演出は `lvh` を検討します
  • 互換性が必要な案件は `vh` フォールバックを必ず残します

よくある質問

vhはもう不要ですか

不要ではありません。古い環境を考慮する案件では、vh をフォールバックとして残す構成が実務的です。新単位に対応した環境だけを上書きする実装が安全です。

dvhだけ使えば十分ですか

要件次第です。dvh は追従性が高い反面、UI変化時に再レイアウトが目立つ場合があります。安定表示を優先する領域は svh の方が扱いやすいことがあります。

lvhの実用場面はありますか

あります。ブラウザUIが引っ込んだ状態で広い表示を取りたいビジュアル重視のセクションでは有効です。ただしUI表示時の見切れリスクがあるため、重要な操作要素には慎重に使います。

WordPressテーマでも同じ考え方ですか

同じです。テンプレート構造に関係なく、要素ごとに単位を選ぶ設計がポイントです。特に固定ヘッダーや固定CTAがあるテーマでは、safe-area と合わせて確認すると不具合を減らせます。

まとめ

lvh・svh・dvhは「どのビューポート状態を基準にするか」を選ぶための単位です。実装時は、まず `vh` フォールバックを置き、隠したくない領域を `svh`、追従させたい領域を `dvh`、演出優先の広い表示に `lvh` を使い分けてください。最後に実機でスクロール、キーボード、画面回転を確認すれば、モバイル特有の崩れをかなり減らせます。

この記事を書いた人
Naokazu Yokoo

エンジニア歴20年以上。現在はWeb / AI領域で活動中。
開発環境・サーバー環境ともに速度と効率性を追求しています。

Follow Naokazu Yokoo
Follow Naokazu Yokoo

Comment

タイトルとURLをコピーしました