2026.09.15 泊まれる場所4,223 立ち寄りスポット46,522 営業中を確認したキャンプ場1,005 note を読む

100vhでスマホの下が切れる原因|トップページの写真の下だけ、いつも指で押さないと見えなかった

トップページの写真をheight:100vhで画面いっぱいにしたら、スマホでだけ下が切れて見えた。
アドレスバーの出し引きで、100vhの「100%」の中身がそもそも違っていた。

トップページの一枚目、キャンプ場の写真を画面いっぱいに出したくて height: 100vh を書いた。
パソコンで見るぶんには狙いどおりで、写真の下端がちょうど画面の下端に合う。
満足してスマホで確認したら、様子が違った。

写真の下、数十ピクセルぶんだけ次のセクションの白地が見えている。
指で軽くスクロールすると写真は画面いっぱいに収まるのに、ページを開いた直後だけ下が切れて見える。
再現するたびに条件が違う気がして、最初はキャッシュのせいだと思っていた。

職業柄、こういうときはブラウザのせいにする前に自分のCSSを疑う癖がついている。
それでも見直した数値に間違いはなく、パソコンでは何度確認しても正しく表示される。
スマホでだけ起きる、というところが手がかりだった。

100vhの「100%」は、実は毎回違う数字だった

vh は viewport height の略で、画面の高さの1%を表す単位だと覚えていた。
スマホの場合、その「画面の高さ」の中に、アドレスバーやタブバーといったブラウザ自身のUIが含まれるかどうかで数字が変わる。

ページを開いた直後は、上にアドレスバー、下にツールバーが表示された状態が初期値になっていることが多い。
その状態から下にスクロールすると、ブラウザが「読むのを邪魔しない」と判断してアドレスバーを画面外へ隠す。
隠れた分だけ、実際に見えている領域は広がる。

ここで問題になるのが、100vh がどちらの状態を基準に計算されているかだ。
ブラウザによっては、アドレスバーが隠れた「いちばん広い状態」を基準に100vhを固定していた。
ページを開いた直後、アドレスバーがまだ表示されている狭い状態では、100vh分の高さが画面からはみ出す。
はみ出した分だけ、写真の下が見えなくなっていた。

直すために新しく増えた単位

この不一致は僕だけが踏んでいたものではなく、CSSの仕様を決めている団体(W3CのCSS Working Group)でも問題として扱われ、新しい単位が追加されていた。

svh(small viewport height)は、アドレスバーが出ている「いちばん狭い状態」を基準にする単位。
lvh(large viewport height)は逆に、アドレスバーが隠れた「いちばん広い状態」を基準にする単位。
そして dvh(dynamic viewport height)は、アドレスバーの出し引きに合わせてその場で数字が変わる単位だった。

いちばん自分の状況に合っていたのは dvh のほうだ。
ページを開いた瞬間の狭い状態でも、スクロール後の広い状態でも、常にそのときの実際の表示領域に合わせて高さが決まる。
アドレスバーが隠れた瞬間、写真の高さもふわっと追従して伸びる。

書き換えたのは1行、でも順番が要る

該当のCSSを、こう書き換えた。

height: 100vh;
height: 100dvh;

同じプロパティを2回書くのは無駄に見えるけれど、これには理由がある。
dvh をまだ知らない古いブラウザは、知らない単位の行をそのまま読み飛ばす仕様になっている。
先に書いた 100vh が生きたまま残るので、古い環境でも最低限の高さは確保される。
新しい環境では後から書いた 100dvh が上書きして効く。
新旧どちらの見え方も一気に切り捨てずに済む、費用対効果のいい直し方だった。

直したあと、もう一度スマホで開き直した。
ページを開いた瞬間から写真は画面ぴったりに収まり、スクロールでアドレスバーが隠れても下に不自然な隙間はできなかった。
数値をいじって力業で調整していた頃の自分に、単位を変えるだけでいいと教えてやりたい。

いま思えば、100vhでレイアウトが崩れる相談を過去にも何度か見かけていた。
そのたびに「スマホのブラウザは癖が強い」くらいに片付けていたけれど、癖ではなく仕様の解釈違いだったらしい。
画面いっぱいに何かを表示したいときは、最初から vh ではなく dvh を書く。
いまはそれを自分の既定値にしている。

まる子パパ

まる子パパ

会社員。受託開発のエンジニアで、その前は寿司職人・長距離運転手・農業。 技術ブログは、キャンプの合間に踏んだバグと、AI・Web開発の運用の失敗を書いています。 このサイト自体が、開発に携わっているCMS「コンテナ」の稼働中の実例です。 このサイトについて

ほかにも書いています

note・スタンプ

※noteは運営者が個人で書いているものです。

技術ブログ一覧へ戻る