svh・lvh・dvhとは?CSSの新しいビューポート単位の違いと使い分けをコード例付きで解説
CSSでファーストビューやフルスクリーン風のレイアウトを作るとき、以前は height: 100vh; や min-height: 100vh; がよく使われていました。しかし、スマートフォンのブラウザではアドレスバーや下部ナビゲーションが表示されたり隠れたりするため、100vh が実際に見えている画面の高さと合わないことがあります。その結果、画面下のボタンが隠れる、ファーストビューが少しはみ出す、余計なスクロールが発生する、中央配置がずれて見えるといった問題が起こりやすくなります。
この問題に対応するために登場したのが、svh、lvh、dvh という新しいビューポート高さ単位です。svh は small viewport height、lvh は large viewport height、dvh は dynamic viewport height を意味します。簡単に言えば、svh はブラウザUIが表示されている小さい表示領域、lvh はブラウザUIが隠れた大きい表示領域、dvh は現在の状態に合わせて変化する表示領域を基準にします。本記事では、この3つの違い、使いどころ、注意点、実務で使えるコード例を詳しく解説します。
1. svh・lvh・dvhが必要になった理由
まずは、なぜ従来の vh だけでは不十分になったのかを理解する必要があります。特にスマートフォンでは、ブラウザのUIが常に同じ高さで表示されているわけではありません。ユーザーがスクロールするとアドレスバーが縮んだり、戻ったりするため、画面の「見える高さ」が変化します。この変化を無視して 100vh だけで設計すると、実際の表示とCSS上の計算がずれてしまいます。
1.1 従来の100vh問題
従来の 100vh は、画面の高さを使ってフルスクリーン風のセクションを作るために便利でした。たとえば、トップページのヒーローセクションを画面いっぱいに見せたい場合、min-height: 100vh; を指定すれば、パソコンではかなり自然に表示できます。しかし、スマートフォンではブラウザのアドレスバーや下部UIが表示されるため、実際にユーザーが見られる高さよりも 100vh の方が大きく扱われることがあります。その結果、下部に配置したCTAボタンやフォームの送信ボタンが画面外に隠れることがあります。
この問題は、特にLP、ログイン画面、予約フォーム、スマートフォン向けWebアプリで起こりやすいです。ファーストビューを綺麗に中央配置したつもりでも、実機で見ると少し下にずれていたり、ボタンを押すために余計なスクロールが必要になったりします。svh、lvh、dvh は、このようなモバイルブラウザ特有の高さの変化をより正確に扱うための単位です。
.hero-old { min-height: 100vh; display: grid; place-items: center;}
1.2 モバイルブラウザのUIが高さを変える
スマートフォンのブラウザでは、ページを開いた直後はアドレスバーや下部ナビゲーションが表示されていることが多く、スクロールするとそれらが縮んだり隠れたりします。つまり、同じ端末でも、ブラウザUIが表示されている状態と隠れている状態では、Webページが実際に使える高さが変わります。従来の vh は、この変化を細かく扱うには不十分な場面がありました。
たとえば、画面下に「今すぐ申し込む」ボタンを固定的に配置している場合、ブラウザUIが表示されている状態ではボタンが隠れたり、逆にUIが隠れた状態では余白が大きく見えたりすることがあります。svh、lvh、dvh を使うと、ブラウザUIが表示されている状態を基準にするのか、隠れた状態を基準にするのか、現在の状態に合わせるのかを選べるようになります。
.mobile-layout { min-height: 100svh; padding: 24px;}
1.3 新しい単位で高さの基準を選べる
svh、lvh、dvh の大きなメリットは、開発者が高さの基準を選べるようになったことです。常に安全に画面内へ収めたいなら svh、ブラウザUIが隠れた最大表示領域を使いたいなら lvh、現在の表示状態に合わせたいなら dvh を選べます。これにより、従来の 100vh だけでは難しかった細かいレスポンシブ調整がしやすくなります。
たとえば、ログイン画面のようにボタンを必ず画面内に収めたい場合は 100svh が向いています。一方、没入感のあるヒーローセクションでは 100lvh を使って大きく見せる選択もあります。Webアプリのように現在の表示領域にぴったり合わせたい場合は 100dvh が便利です。
.safe-screen { min-height: 100svh;}.large-screen { min-height: 100lvh;}.dynamic-screen { min-height: 100dvh;}
1.4 vhとの関係を理解する
従来の vh は、現在では lvh に近い扱いとして理解されることが多く、MDNでも vh は large viewport size に基づく lvh と同等と説明されています。つまり、100vh は安全な小さい表示領域ではなく、ブラウザUIが隠れたときの大きい表示領域に近い基準として考える必要があります。
そのため、スマートフォンで「画面内に必ず収めたい」要素に 100vh を使うと、意図しないはみ出しが起きることがあります。これからの実装では、従来どおり vh を使い続けるのではなく、目的に応じて svh、lvh、dvh を選ぶ考え方が重要です。
/* 従来の書き方 */.hero { min-height: 100vh;}/* 目的に応じて新しい単位を使う */.hero-safe { min-height: 100svh;}.hero-dynamic { min-height: 100dvh;}
2. svhとは何か
svh は small viewport height の略で、ブラウザUIが表示されている状態の小さいビューポート高さを基準にする単位です。画面内に確実に収めたいレイアウトや、下部のボタンが隠れてほしくない画面で特に役立ちます。安全性を優先したい場合に選びやすい単位です。
2.1 svhは小さい表示領域を基準にする
svh は、small viewport height を基準にした単位です。これは、ブラウザのアドレスバーや下部ナビゲーションなどのUIが表示されている状態、つまりWebページが使える高さが小さくなっている状態を想定した単位です。100svh と指定すると、小さい表示領域の100%を使うため、スマートフォンでコンテンツが画面外にはみ出しにくくなります。
この性質により、svh は安全な高さ指定に向いています。特に、ファーストビュー内に見出し、説明文、CTAボタンをすべて収めたい場合や、ログインフォーム、会員登録フォーム、予約フォームのように重要な操作要素を画面内に見せたい場合に便利です。ブラウザUIが表示されている状態でも収まる高さを基準にするため、ユーザーが最初にページを開いた瞬間の見え方を安定させやすくなります。
.hero-safe { min-height: 100svh; display: grid; place-items: center; padding: 24px;}
2.2 svhは下部ボタンを守りやすい
スマートフォン向けのページでは、画面下にCTAボタン、送信ボタン、次へ進むボタンなどを配置することがあります。このとき、100vh を使っていると、ブラウザの下部UIやアドレスバーの影響でボタンが隠れる可能性があります。svh は小さい表示領域を基準にするため、ブラウザUIが表示されている状態でもボタンを見せやすくなります。
たとえば、LPのファーストビューで「無料で相談する」ボタンを画面下寄りに置く場合、min-height: 100svh; を使うと、初期表示でボタンが画面外に押し出されるリスクを減らせます。特に、広告流入のLPや登録フォームでは、最初の画面でCTAが見えるかどうかが成果に影響するため、svh の安全性は実務上かなり重要です。
.hero-cta { min-height: 100svh; display: flex; flex-direction: column; justify-content: space-between; padding: 24px;}
2.3 svhはログイン画面に向いている
ログイン画面や登録画面では、入力欄、パスワード、エラーメッセージ、送信ボタンなどを画面内に自然に収める必要があります。100vh を使うと、スマートフォンで下部ボタンが隠れたり、キーボード表示時にレイアウトが窮屈になったりする場合があります。100svh を使うと、少なくともブラウザUIが表示されている小さい状態を基準にできるため、初期表示の安定性が高くなります。
ただし、フォームではキーボード表示によってさらに表示領域が変わるため、svh だけで完全に解決できるわけではありません。実務では、min-height: 100svh; に加えて、フォームカードに max-height や overflow-y: auto; を設定し、内容が増えたときに内部スクロールできるようにしておくと安全です。
.login-page { min-height: 100svh; display: flex; align-items: center; justify-content: center; padding: 20px;}.login-card { width: min(100%, 420px); max-height: calc(100svh - 40px); overflow-y: auto;}
2.4 svhの注意点
svh は安全側の高さを使える反面、ブラウザUIが隠れて表示領域が広くなった場合でも、要素の高さは小さいビューポート基準のままになります。そのため、スクロール後に画面が広くなったとき、下に余白が残ったり、ファーストビューが少し小さく見えたりする場合があります。安全性を重視する代わりに、画面いっぱいの迫力は少し弱くなることがあります。
そのため、svh は「常に最大限大きく見せたい」場面よりも、「確実に画面内へ収めたい」場面で使うのが向いています。ログイン画面、フォーム、重要なCTA、スマートフォンの初期表示などでは有効ですが、ブランドサイトの大きなビジュアル表現では lvh や dvh の方が自然な場合もあります。
.safe-first-view { min-height: 100svh; padding: clamp(24px, 5vw, 64px);}.visual-first-view { min-height: 100dvh;}
3. lvhとは何か
lvh は large viewport height の略で、ブラウザUIが隠れた状態の大きいビューポート高さを基準にする単位です。画面を広く使いたい場合、没入感のあるビジュアル表現を作りたい場合、大きなファーストビューを設計したい場合に使われます。ただし、初期表示では一部が隠れる可能性があるため注意が必要です。
3.1 lvhは大きい表示領域を基準にする
lvh は、large viewport height を基準にする単位です。これは、ブラウザのアドレスバーやナビゲーションUIが隠れて、Webページが使える高さが大きくなった状態を想定します。100lvh と指定すると、大きい表示領域の100%を使うため、画面を広く使ったレイアウトを作れます。従来の vh に近い感覚で使える単位でもあります。
lvh は、ブランドサイトやキャンペーンサイトのように、ファーストビューの迫力を出したい場面で使いやすいです。ブラウザUIが隠れた後の広い表示領域を前提にするため、背景画像や動画、ビジュアル要素を大きく見せられます。ただし、ページを開いた直後にブラウザUIが表示されている状態では、下部が隠れる可能性があるため、重要なボタンや入力欄を下端ぎりぎりに配置するのは避けた方が安全です。
.hero-large { min-height: 100lvh; display: grid; place-items: center;}
3.2 lvhはビジュアル重視のファーストビューに向いている
lvh は、大きな画像や動画を使ったファーストビューと相性が良いです。ユーザーが少しスクロールしてブラウザUIが隠れたとき、画面いっぱいに広がるビジュアルを見せられるため、没入感のあるデザインを作りやすくなります。特に、コーポレートサイトのメインビジュアル、ブランドLP、採用サイトのキービジュアルなどでは、画面を広く使うことで印象を強められます。
ただし、lvh は安全性よりも大きさを優先する単位です。スマートフォンでページを開いた直後は、ブラウザUIが表示されているため、100lvh の下部が実際の表示領域からはみ出す可能性があります。そのため、重要なCTAやナビゲーションを下端に置く場合は、余白を多めに取るか、svh や dvh を検討する必要があります。
.visual-hero { min-height: 100lvh; background-image: url("hero.jpg"); background-size: cover; background-position: center; padding: clamp(32px, 6vw, 96px);}
3.3 lvhはvhに近い感覚で使える
従来の vh に慣れている場合、lvh は比較的理解しやすい単位です。なぜなら、lvh は大きいビューポートを基準にするため、従来の 100vh に近い見え方になることが多いからです。MDNでも、vh は large viewport size に基づく lvh と同等の単位として説明されています。
そのため、既存の 100vh レイアウトを明示的に新しい単位へ置き換える場合、まず 100lvh を検討できます。ただし、置き換えたからといってモバイルの下部隠れ問題が解決するわけではありません。lvh はあくまで大きい表示領域を使う単位なので、安全に収めたい場面では svh や dvh の方が適しています。
/* 従来 */.hero-old { min-height: 100vh;}/* 意図を明確にする */.hero-large { min-height: 100lvh;}
3.4 lvhの注意点
lvh の注意点は、初期表示の安全性が低くなる場合があることです。ブラウザUIが表示されている状態では、実際に見える領域が 100lvh より小さいため、下部のコンテンツが隠れることがあります。特に、下端に固定的なボタンや重要な説明文を置いている場合、ユーザーが最初に見たときに要素が欠けて見える可能性があります。
そのため、lvh は「画面全体を大きく使うこと」が目的の場面に向いています。逆に、「初期表示で必ず全要素を見せたい」「ボタンを画面内に収めたい」「フォームを安全に表示したい」という場面では、svh や dvh を使った方が実務的です。lvh は迫力を出す単位、svh は安全に収める単位と考えると使い分けやすくなります。
.hero-with-bottom-button { min-height: 100lvh; padding-bottom: max(32px, env(safe-area-inset-bottom));}.hero-safe-button { min-height: 100svh;}
4. dvhとは何か
dvh は dynamic viewport height の略で、現在のビューポート高さに合わせて動的に変化する単位です。ブラウザUIが表示されているときは小さく、隠れたときは大きくなるため、実際の表示状態に合わせたレイアウトを作りやすくなります。Webアプリやモーダル、チャットUIなどで特に便利です。
4.1 dvhは現在の表示領域を基準にする
dvh は、dynamic viewport height を基準にする単位です。これは、ブラウザUIの表示状態に応じて現在のビューポート高さを反映します。たとえば、アドレスバーが表示されているときは小さい高さになり、スクロールによってアドレスバーが隠れると大きい高さになります。100dvh は、その瞬間の表示領域の100%を意味します。
この性質により、dvh は「今見えている画面にぴったり合わせたい」場面で非常に便利です。従来の 100vh では、スマートフォンで実際の表示領域とズレることがありましたが、dvh を使うことで、現在の表示状態に近い高さを扱いやすくなります。Web.devでも、small、large、dynamic viewport units はモバイルの動的なブラウザUI問題に対応するための新しい単位として紹介されています。
.app-screen { min-height: 100dvh; display: flex; flex-direction: column;}
4.2 dvhはWebアプリに向いている
Webアプリでは、画面全体を使ってヘッダー、メインコンテンツ、下部ナビゲーションを配置することがあります。このようなUIでは、現在の表示領域に合わせて高さを調整できる dvh が便利です。100dvh を使えば、ブラウザUIの状態に応じてアプリ全体の高さが変わるため、固定の 100vh よりも実際の画面に合いやすくなります。
たとえば、チャット画面では、上部にヘッダー、中央にメッセージ一覧、下部に入力欄を配置します。100dvh を使うことで、表示領域に合わせて中央エリアを伸縮させやすくなります。ただし、dvh はスクロール中に値が変化することがあるため、要素が頻繁にリサイズされると違和感が出る場合もあります。重要なアニメーションや重いレイアウトでは注意が必要です。
.chat-app { height: 100dvh; display: grid; grid-template-rows: auto 1fr auto;}.chat-messages { overflow-y: auto;}
4.3 dvhはモーダルにも使いやすい
モーダルやドロワー、ボトムシートのように、現在の画面内に収めたいUIでは dvh が役立ちます。max-height: calc(100dvh - 32px); のように指定すれば、現在の表示領域から余白を引いた高さを上限にできます。これにより、モーダルの内容が多い場合でも画面外にはみ出しにくく、内部スクロールで対応しやすくなります。
特にスマートフォンでは、モーダルが画面下部に寄るボトムシート型UIがよく使われます。このとき vh を使うと、ブラウザUIの影響で下部が隠れたり、余計な余白が出たりする可能性があります。dvh を使うことで、現在の表示領域に合わせた自然な高さ制御がしやすくなります。
.modal { width: min(100% - 32px, 560px); max-height: calc(100dvh - 32px); overflow-y: auto; border-radius: 24px;}
4.4 dvhの注意点
dvh は現在の表示領域に合わせて変化するため、スクロール中やブラウザUIの表示切り替え時に要素の高さが変わることがあります。これは便利な一方で、ユーザーがスクロールしている最中にレイアウトが動いて見える場合があります。特に、ヒーローセクションの高さや背景画像の位置が頻繁に変わると、視覚的に落ち着かない印象になることがあります。
そのため、dvh は「現在の画面に合わせる必要があるUI」に使うと効果的ですが、単なる装飾的なセクションに何でも使えばよいわけではありません。チャット、モーダル、アプリ画面、下部固定UIなどでは便利ですが、スクロール中の安定感を重視するLPのファーストビューでは、svh や lvh の方が適している場合もあります。
/* 動的に合わせたいUI */.app-layout { height: 100dvh;}/* 安定した初期表示を優先したい場合 */.safe-hero { min-height: 100svh;}
5. svh・lvh・dvhの違い
ここまで個別に見てきたように、svh、lvh、dvh はすべて高さに関するビューポート単位ですが、基準にする表示領域が異なります。実務では、この違いを「安全に収める」「大きく見せる」「現在に合わせる」という3つの目的で理解すると使いやすくなります。
5.1 svhは安全、lvhは大きさ、dvhは現在値
svh は小さい表示領域を基準にするため、安全に画面内へ収めたい場合に向いています。lvh は大きい表示領域を基準にするため、ブラウザUIが隠れた状態の広い画面を使いたい場合に向いています。dvh は現在の表示領域を基準にするため、ブラウザUIの状態に合わせて動的に変化させたい場合に向いています。
この3つを一言で分けるなら、svh は「安全」、lvh は「最大」、dvh は「現在」です。どれが一番良いというより、画面の目的によって選ぶべき単位が変わります。CTAを確実に見せたいなら svh、ビジュアルを大きく見せたいなら lvh、アプリUIを現在の画面に合わせたいなら dvh が候補になります。
.safe { min-height: 100svh;}.large { min-height: 100lvh;}.dynamic { min-height: 100dvh;}
5.2 初期表示を重視するならsvh
ページを開いた瞬間の見え方を安定させたい場合は、svh が向いています。ユーザーがまだスクロールしておらず、ブラウザUIが表示されている状態でも、コンテンツを画面内に収めやすいからです。特に、広告から流入するLP、申し込み画面、ログイン画面、重要なCTAがあるファーストビューでは、初期表示の安全性が重要になります。
たとえば、ファーストビュー内に見出し、説明文、ボタン、補足情報をすべて入れたい場合、100lvh では下部が隠れる可能性があります。100svh を使えば、小さい表示領域を前提にレイアウトできるため、初回表示での欠けを防ぎやすくなります。
.lp-first-view { min-height: 100svh; display: flex; flex-direction: column; justify-content: center; gap: 24px;}
5.3 ビジュアル重視ならlvh
画面全体を大きく使ったビジュアル表現を重視する場合は、lvh が向いています。たとえば、背景動画や大きな写真を使ったヒーローセクションでは、ブラウザUIが隠れた状態の大きな表示領域を基準にした方が、迫力のある見た目を作れます。ブランドサイトや採用サイトのキービジュアルでは、このような大きさが効果的な場合があります。
ただし、lvh は安全性よりも最大表示を優先するため、重要な情報を下端に置く場合は注意が必要です。ビジュアルは大きく見せつつ、CTAやテキストは中央寄りに配置するなど、初期表示で隠れにくい設計にすると使いやすくなります。
.brand-hero { min-height: 100lvh; display: grid; place-items: center; background: url("brand-hero.jpg") center / cover;}
5.4 画面状態に合わせたいならdvh
現在の表示領域に合わせてUIを調整したい場合は、dvh が向いています。特に、Webアプリ、チャット画面、モーダル、ドロワー、下部固定ナビゲーションのある画面では、現在のビューポートにぴったり合わせられることが重要です。100dvh を使うことで、ブラウザUIの状態に応じて高さを調整できます。
ただし、dvh は動的に変化するため、スクロール中にレイアウトが動いて見える可能性があります。静的なLPの装飾セクションより、アプリ的な画面や固定UIのように「現在の表示領域に合わせる必要がある場所」で使うと効果的です。
.mobile-app { height: 100dvh; display: grid; grid-template-rows: auto 1fr auto;}.mobile-app__main { overflow-y: auto;}
6. 実務での使い分け
svh、lvh、dvh は、単位の意味を覚えるだけではなく、画面の目的に合わせて選ぶことが重要です。ここでは、ファーストビュー、フォーム、Webアプリ、モーダルなど、実務でよく出てくる場面ごとに使い分けを整理します。
6.1 ファーストビューでは目的で選ぶ
ファーストビューでは、何を優先するかによって使う単位が変わります。ボタンや説明文を初期表示で確実に見せたい場合は svh が向いています。ビジュアルを画面いっぱいに大きく見せたい場合は lvh が向いています。ブラウザUIの変化に合わせて高さを調整したい場合は dvh が使えます。
たとえば、問い合わせ獲得を目的としたLPでは、CTAが隠れないことが重要なので 100svh が安全です。一方、ブランドイメージを強く見せるトップページでは、100lvh で大きなビジュアルを見せる選択もあります。目的を決めずに何となく 100dvh を使うのではなく、ファーストビューの役割から判断することが大切です。
.hero-conversion { min-height: 100svh;}.hero-branding { min-height: 100lvh;}.hero-adaptive { min-height: 100dvh;}
6.2 フォーム画面ではsvhが安全
フォーム画面では、入力欄や送信ボタンが画面外に隠れるとユーザー体験が大きく悪化します。そのため、初期表示で安全に収めやすい svh が向いています。特に、ログイン、会員登録、問い合わせ、予約、決済前の入力画面では、ボタンが見えること、入力欄が押しやすいこと、エラー表示が確認しやすいことが重要です。
ただし、スマートフォンではキーボード表示時にさらに画面が狭くなるため、svh だけで完璧に対応できるわけではありません。フォームカードに max-height と overflow-y: auto; を設定し、必要に応じて内部スクロールできるようにしておくと、実務での安定性が高まります。
.form-page { min-height: 100svh; display: grid; place-items: center; padding: 20px;}.form-card { width: min(100%, 480px); max-height: calc(100svh - 40px); overflow-y: auto;}
6.3 Webアプリではdvhが便利
Webアプリでは、画面全体をひとつのアプリケーション領域として扱うことが多く、現在の表示領域に合わせて高さを調整できる dvh が便利です。たとえば、ヘッダー、メインエリア、フッター、下部ナビゲーションを持つ画面では、height: 100dvh; を使うことで、現在のビューポートに合わせたレイアウトを作りやすくなります。
特に、メインエリアだけをスクロールさせたい場合、外側のアプリコンテナに height: 100dvh; を指定し、中央の領域に overflow-y: auto; を設定すると扱いやすくなります。これにより、ヘッダーや下部ナビゲーションを固定しながら、コンテンツだけをスクロールできます。
.app-shell { height: 100dvh; display: grid; grid-template-rows: auto 1fr auto;}.app-main { overflow-y: auto;}
6.4 モーダルではdvhとmax-heightを組み合わせる
モーダルでは、現在の画面内に収めることが重要です。特にスマートフォンでは、モーダルが画面からはみ出すと閉じるボタンが押せなかったり、内容が読めなかったりします。dvh と max-height を組み合わせることで、現在の表示領域に合わせた高さ制限を作れます。
たとえば、max-height: calc(100dvh - 32px); と指定すれば、上下に16pxずつ余白を確保しながら、モーダルが現在の画面内に収まりやすくなります。内容が多い場合は overflow-y: auto; で内部スクロールさせると、画面全体のスクロールを乱さずに操作できます。
.dialog { width: min(100% - 32px, 560px); max-height: calc(100dvh - 32px); overflow-y: auto; border-radius: 20px;}
7. svh・lvh・dvhとsafe-areaの関係
スマートフォンでは、ビューポート高さだけでなく、ノッチ、ホームインジケーター、セーフエリアも考える必要があります。svh、lvh、dvh を使って高さを調整しても、画面端にボタンを置く場合は env(safe-area-inset-bottom) などを組み合わせた方が安全です。
7.1 safe-areaとは何か
safe-areaとは、スマートフォンのノッチ、角丸、ホームインジケーターなどにコンテンツが重ならないようにするための安全領域です。特にiPhoneのように画面下部にホームインジケーターがある端末では、ボタンを画面下ぎりぎりに置くと、操作しづらくなることがあります。CSSでは env(safe-area-inset-bottom) などを使って、この安全領域分の余白を確保できます。
svh、lvh、dvh は高さの基準を調整する単位ですが、safe-areaは画面端の物理的・UI的な余白に関係します。つまり、100dvh を使って現在の高さに合わせても、下部のボタンがホームインジケーターに近すぎる場合があります。そのため、下部固定ボタンやフッターでは safe-area を考慮することが重要です。
.bottom-bar { padding-bottom: env(safe-area-inset-bottom);}
7.2 下部固定ボタンではsafe-areaを足す
スマートフォン向けのLPやWebアプリでは、下部に固定CTAボタンを置くことがあります。この場合、position: fixed; bottom: 0; だけでは、ホームインジケーターやブラウザUIと近くなりすぎることがあります。env(safe-area-inset-bottom) を使って下部余白を追加すると、より安全な配置になります。
たとえば、下部固定バーに padding-bottom: max(12px, env(safe-area-inset-bottom)); を指定すると、通常時は12px以上の余白を確保し、safe-areaが必要な端末ではその分も考慮できます。dvh や svh と組み合わせることで、高さと端末固有の余白の両方に対応しやすくなります。
.fixed-cta { position: fixed; left: 0; right: 0; bottom: 0; padding: 12px 16px max(12px, env(safe-area-inset-bottom)); background: #ffffff;}
7.3 フルスクリーンUIでは上下の余白を考える
フルスクリーン風のUIを作る場合、height: 100dvh; や min-height: 100svh; だけでなく、上部と下部の安全余白も考える必要があります。特に、上部に戻るボタンや閉じるボタン、下部に送信ボタンやナビゲーションを置く場合、画面端に近すぎると操作しにくくなります。
そのため、フルスクリーンUIでは、padding-top と padding-bottom に env(safe-area-inset-top)、env(safe-area-inset-bottom) を組み合わせると安全です。見た目の余白と端末固有の安全領域を両方考慮することで、スマートフォンでも操作しやすいUIになります。
.fullscreen-panel { min-height: 100dvh; padding-top: max(24px, env(safe-area-inset-top)); padding-bottom: max(24px, env(safe-area-inset-bottom)); padding-inline: 20px;}
7.4 safe-areaを過剰に使いすぎない
safe-areaは便利ですが、すべての要素に過剰に指定すると余白が大きくなりすぎることがあります。基本的には、画面端に接する固定要素、フルスクリーンUI、下部CTA、モーダルの端など、端末のノッチやホームインジケーターと干渉しやすい要素に限定して使うのが実務的です。
通常の本文やカード、セクション内部の余白には、safe-areaよりも通常の padding や clamp() を使う方が自然です。svh、lvh、dvh は高さの調整、safe-areaは画面端の安全余白というように、役割を分けて考えると使いすぎを防げます。
.page-section { padding: clamp(48px, 8vw, 96px) clamp(16px, 5vw, 80px);}.edge-panel { padding-bottom: max(20px, env(safe-area-inset-bottom));}
8. よくある失敗と注意点
svh、lvh、dvh は便利ですが、使い方を間違えると別の表示崩れを生むことがあります。特に、何でも dvh に置き換える、lvh で重要な要素を下端に置く、svh でビジュアルが小さく見える、フォールバックを考えないといった失敗がよくあります。
8.1 何でもdvhに置き換える
dvh は便利なので、従来の 100vh をすべて 100dvh に置き換えたくなるかもしれません。しかし、dvh は動的に変化するため、スクロール中にブラウザUIが変化すると、要素の高さも変わる場合があります。これにより、ヒーローセクションや背景画像が微妙にリサイズされ、視覚的に落ち着かない印象になることがあります。
そのため、dvh は現在の表示領域に合わせる必要があるUIに使うのが基本です。アプリ画面、モーダル、チャット、下部固定UIなどには向いていますが、静的なビジュアルセクションでは svh や lvh の方が適している場合もあります。単位の新しさではなく、レイアウトの目的で選ぶことが重要です。
/* 何でもdvhにしない */.static-hero { min-height: 100svh;}/* 動的に合わせたい画面ではdvh */.app-screen { height: 100dvh;}
8.2 lvhでCTAが隠れる
lvh は大きい表示領域を基準にするため、初期表示では下部が隠れる可能性があります。特に、ファーストビューの一番下にCTAボタンを置いている場合、ブラウザUIが表示された状態ではボタンが見切れることがあります。これは、広告LPや問い合わせ導線のあるページでは大きな問題になります。
lvh を使う場合は、重要なボタンを画面下端ぎりぎりに置かないことが大切です。CTAを中央寄りに配置する、下部に余白を確保する、または svh を使って安全な高さにするなど、目的に合わせて調整します。ビジュアル重視なら lvh、CV重視なら svh と考えると判断しやすくなります。
.hero-risky { min-height: 100lvh; display: flex; align-items: flex-end;}.hero-safe { min-height: 100svh; display: grid; place-items: center;}
8.3 svhで余白が大きく見える
svh は小さい表示領域を基準にするため、ブラウザUIが隠れて画面が広くなった状態では、セクションが少し小さく見える場合があります。特に、背景画像や動画を画面いっぱいに見せたいデザインでは、100svh だと迫力が足りないと感じることがあります。
この場合、初期表示の安全性を優先するのか、スクロール後の大きな表示を優先するのかを決める必要があります。安全性を重視するフォームやCTAでは svh が向いていますが、ビジュアル重視のヒーローでは lvh や dvh の方が自然なこともあります。単位を見た目だけで選ばず、ユーザー行動を基準に判断することが大切です。
.safe-landing { min-height: 100svh;}.visual-landing { min-height: 100lvh;}
8.4 フォールバックを書かない
svh、lvh、dvh は比較的新しいCSS単位なので、プロジェクトによっては古いブラウザや特殊なWebViewへの配慮が必要になる場合があります。現在の主要ブラウザでは広く使いやすくなっていますが、対象ユーザーの環境によってはフォールバックを書いておくと安全です。
実務では、先に従来の 100vh を書き、その後に 100dvh や 100svh を書く方法がよく使われます。対応しているブラウザでは後の指定が適用され、非対応環境では 100vh が残ります。このように段階的に書くことで、新しい単位を使いながら互換性も保ちやすくなります。
.hero { min-height: 100vh; min-height: 100svh;}.app { height: 100vh; height: 100dvh;}
9. 実装例で理解する
ここでは、svh、lvh、dvh を実際のUIでどう使うかを見ていきます。単位の意味だけを覚えるより、ファーストビュー、フォーム、アプリ画面、モーダルのような具体的な場面で理解すると、実務で使いやすくなります。
9.1 CV重視のLPファーストビュー
問い合わせや申し込みを目的としたLPでは、初期表示でCTAボタンが見えることが重要です。ブラウザUIが表示された状態でもボタンが画面内に収まるように、100svh を使うと安全です。見出し、説明文、ボタンの間隔も、画面幅に応じて自然に変わるように clamp() を組み合わせると安定します。
この実装では、ファーストビュー全体の高さを 100svh にし、コンテンツを中央に配置します。ボタンを下端に寄せすぎず、中央付近に置くことで、スマートフォンでも見つけやすく押しやすいCTAになります。CV重視のページでは、ビジュアルの迫力よりも、操作導線の安全性を優先することが大切です。
<section class="lp-hero"> <div class="lp-hero__content"> <h1>スマートフォンでも崩れないLPを作る</h1> <p>新しいビューポート単位で初期表示の安全性を高めます。</p> <a href="#contact">無料で相談する</a> </div></section>
.lp-hero { min-height: 100vh; min-height: 100svh; display: grid; place-items: center; padding: clamp(24px, 5vw, 80px);}.lp-hero__content { width: min(100%, 720px); text-align: center;}
9.2 ブランド重視のビジュアルヒーロー
ブランドサイトや採用サイトでは、ファーストビューの大きな写真や動画で印象を作ることがあります。この場合は、ブラウザUIが隠れた状態の大きい表示領域を使える 100lvh が向いています。画面いっぱいにビジュアルを広げることで、迫力のある見た目を作れます。
ただし、lvh は初期表示で一部が隠れる可能性があるため、重要なテキストやボタンを画面下端ぎりぎりに置かないようにします。中央配置や上寄せ配置を使い、下部には余白を残すと安全です。ビジュアルは大きく、情報は隠れにくく、というバランスが重要です。
<section class="brand-hero"> <div class="brand-hero__copy"> <h1>Design for the next experience</h1> </div></section>
.brand-hero { min-height: 100lvh; display: grid; place-items: center; background: url("brand.jpg") center / cover no-repeat; padding: clamp(32px, 6vw, 96px);}.brand-hero__copy { max-width: 880px;}
9.3 チャットアプリの画面
チャットアプリのようなWebアプリでは、画面全体を現在の表示領域に合わせる必要があります。上部にヘッダー、中央にメッセージ一覧、下部に入力欄を置く場合、height: 100dvh; を使うと、ブラウザUIの状態に合わせてアプリ全体の高さを調整できます。
この実装では、外側の .chat に 100dvh を指定し、Gridで3行に分けています。メッセージ一覧だけをスクロールさせることで、ヘッダーと入力欄を固定したまま、中央の内容を操作できます。Webアプリでは、このように dvh を使うと画面全体の制御がしやすくなります。
<div class="chat"> <header class="chat__header">Chat</header> <main class="chat__messages">...</main> <form class="chat__form">...</form></div>
.chat { height: 100vh; height: 100dvh; display: grid; grid-template-rows: auto 1fr auto;}.chat__messages { overflow-y: auto;}.chat__form { padding-bottom: max(12px, env(safe-area-inset-bottom));}
9.4 ボトムシートモーダル
スマートフォンでは、画面下から出てくるボトムシート型のモーダルがよく使われます。この場合、現在の表示領域に合わせて高さを制限できる dvh が便利です。max-height: calc(100dvh - 24px); のように指定すると、画面上部に少し余白を残しながら、モーダルを現在の画面内に収めやすくなります。
ボトムシートでは、下部のsafe-areaも重要です。ホームインジケーターにボタンが近すぎると操作しにくくなるため、env(safe-area-inset-bottom) を使って下部余白を確保します。dvh とsafe-areaを組み合わせることで、スマートフォンで使いやすいモーダルを作れます。
<div class="bottom-sheet"> <h2>設定</h2> <p>現在の画面内に収まるボトムシートです。</p></div>
.bottom-sheet { position: fixed; left: 12px; right: 12px; bottom: 0; max-height: calc(100dvh - 24px); overflow-y: auto; padding: 24px 20px max(24px, env(safe-area-inset-bottom)); border-radius: 24px 24px 0 0; background: #ffffff;}
10. 実務での判断基準
最後に、実務で迷ったときの判断基準をまとめます。svh、lvh、dvh は新しい単位ですが、難しく考えすぎる必要はありません。基本は、画面内に収めたいのか、大きく見せたいのか、現在の状態に合わせたいのかで選びます。
10.1 安全に収めたいならsvh
初期表示でコンテンツを安全に収めたいなら svh を選びます。ブラウザUIが表示されている小さい状態を基準にするため、スマートフォンでボタンやフォームが隠れるリスクを減らせます。特に、ログイン、登録、問い合わせ、予約、CV重視のLPでは svh が実務的です。
ただし、svh は小さい表示領域を基準にするため、ブラウザUIが隠れた後は少し余白が大きく見えることがあります。ビジュアルの迫力よりも操作性や安全性を重視する画面に使うと、単位の特徴を活かしやすくなります。
.safe-layout { min-height: 100vh; min-height: 100svh; display: grid; place-items: center;}
10.2 大きく見せたいならlvh
ビジュアルを大きく見せたいなら lvh を選びます。ブラウザUIが隠れた状態の大きい表示領域を基準にするため、画面いっぱいの写真、動画、背景表現に向いています。ブランドサイト、採用サイト、キャンペーンサイトのように印象を重視するファーストビューで使いやすい単位です。
ただし、lvh は初期表示で下部が隠れる可能性があるため、重要なCTAや入力欄を下端に置くのは避けた方が安全です。大きなビジュアルを見せつつ、重要な情報は中央寄りに配置するなど、見た目と操作性のバランスを取ることが重要です。
.large-visual { min-height: 100lvh; background-size: cover; background-position: center;}
10.3 現在の画面に合わせたいならdvh
現在の表示領域に合わせたいなら dvh を選びます。ブラウザUIが表示されているときも、隠れているときも、その時点の高さに合わせて変化するため、Webアプリ、チャット、モーダル、ドロワー、ボトムシートなどに向いています。特に、画面全体をUIとして扱う場合に便利です。
ただし、dvh は動的に変化するため、スクロール中にレイアウトが動くことがあります。静的なビジュアルセクションでは違和感が出る場合もあるため、現在の表示領域に合わせる必要があるUIに限定して使うと安定します。
.dynamic-layout { height: 100vh; height: 100dvh; display: grid; grid-template-rows: auto 1fr auto;}
10.4 迷ったら用途で分ける
実務で迷った場合は、まず画面の目的を決めます。CV重視でボタンを見せたいなら svh、ビジュアル重視で大きく見せたいなら lvh、アプリUIとして現在の画面に合わせたいなら dvh を選びます。この判断基準を持っておくと、単位選びで迷いにくくなります。
また、互換性を考えて、必要に応じて vh をフォールバックとして先に書くと安全です。新しい単位だけに頼るのではなく、既存の vh と組み合わせて段階的に書くことで、より安定したCSSになります。
/* CV重視 */.hero-cv { min-height: 100vh; min-height: 100svh;}/* ビジュアル重視 */.hero-visual { min-height: 100lvh;}/* アプリUI */.app-ui { height: 100vh; height: 100dvh;}
おわりに
svh、lvh、dvh は、従来の vh だけでは扱いにくかったスマートフォンのビューポート高さ問題に対応するための新しいCSS単位です。svh はブラウザUIが表示されている小さい表示領域、lvh はブラウザUIが隠れた大きい表示領域、dvh は現在の表示状態に応じた動的な表示領域を基準にします。この違いを理解すると、ファーストビュー、フォーム、Webアプリ、モーダル、下部固定UIなどで、より正確な高さ設計ができるようになります。
実務では、画面内に安全に収めたい場合は svh、大きなビジュアルを見せたい場合は lvh、現在の画面状態に合わせたい場合は dvh を選ぶと分かりやすくなります。ただし、どの単位も万能ではありません。svh は安全ですが少し小さく見える場合があり、lvh は迫力がありますが初期表示で下部が隠れる可能性があり、dvh は便利ですがスクロール中に高さが変わる場合があります。
これからのレスポンシブデザインでは、単に 100vh を使うのではなく、画面の目的に合わせて 100svh、100lvh、100dvh を選ぶことが重要です。さらに、env(safe-area-inset-bottom)、clamp()、max-height、overflow-y: auto; などを組み合わせることで、スマートフォンでも操作しやすく、表示崩れに強いUIを作れます。CSSの新しいビューポート単位を正しく使い分けることで、モバイル時代に合った安定したレスポンシブ設計を実現できます。
EN
JP
KR