iOS 15.4で追加されたCSS単位「dvh」が高さ100%問題を解決する
iOS 15.4でSafariに様々なアップデートがありましたが dvh
という単位が追加されたことがWeb開発において大きな意味を持ちます。
これまでiOS Safariではスクロールを始めるとURLバーが小さくなり画面のサイズが変わるという問題がありました。
そのため高さ100%を「URLバーが大きい状態」と「URLバーが小さい状態」のどちらかで設定する必要があり、現在のURLバーの状態を反映した高さ100%をCSSだけで実現することは難しかったのです。
これを解決するのが dvh
です。
結論
これまで height: 100%;
や height: 100vh;
と記述していた部分を height: 100dvh;
と記述すればOK。
これまでの解決策
これまでiOS Safariで高さ100%を実現するためにはいくつかのパターンがありました。
100%
パターン1: パーセントで指定するパターンです。
ただしこの場合は高さ100%にしたい要素がHTMLタグで下層にある場合、すべての要素に100%を記述する必要があるという面倒な方法でした。
vh
単位が誕生する前の古の方法でもあります。
この場合は、URLバーの状態を反映した高さ100%が実現出来ますが <html>
タグまで height: 100%;
を伝播していくのは大変です。
<!DOCTYPE html>
<html style="height: 100%">
<body style="margin: 0; color: white; font-family: sans-serif; height: 100%">
<div style="height: 100%">
<div
style="
height: 100%;
background-color: gray;
display: flex;
justify-content: center;
align-items: center;
"
>
<div>Center</div>
</div>
<div style="height: 100%; background-color: black; text-align: center">
<div>Test</div>
</div>
</div>
</body>
</html>
100vh
パターン2: CSS3で vh
単位が登場して以降はこれを使用することが一般的になりました。
高さの伝播が必要ないことが最大の特徴です。
ただし、高さは「URLバーが小さい状態」の高さに固定されてしまいます。
コンテナの高さが大きいので縦の中央寄せも上手く機能しません。
<!DOCTYPE html>
<html>
<body style="margin: 0; color: white; font-family: sans-serif">
<div>
<div
style="
height: 100vh;
background-color: gray;
display: flex;
justify-content: center;
align-items: center;
"
>
<div>Center</div>
</div>
<div style="height: 100vh; background-color: black; text-align: center">
<div>Test</div>
</div>
</div>
</body>
</html>
(パターン3: JavaScript)
今回はCSSだけで実装することを前提にしていますが、JavaScriptを使用すればこれまでも、URLバーの状態を反映した高さ100%を実現することはできました。
しかしながら、簡単な表示の制御をするためだけにJavaScriptを書くことは面倒でした。
新しい解決策
新しい解決策である dvh
タグは、これまで vh
タグを使用していた場所をそのまま置き換えるだけで自動的にURLバーの状態を反映した高さ100%になります。
<!DOCTYPE html>
<html>
<body style="margin: 0; color: white; font-family: sans-serif">
<div>
<div
style="
height: 100dvh;
background-color: gray;
display: flex;
justify-content: center;
align-items: center;
"
>
<div>Center</div>
</div>
<div style="height: 100dvh; background-color: black; text-align: center">
<div>Test</div>
</div>
</div>
</body>
</html>
最高です!🙌
これからは vh
ではなく dvh
を使っていきましょう。
注意点
dvh
はまだ実装が広まっていない新しい単位です。Safari 15.4以外の環境ではGoogle Chromeですら実装していません。ですので必ずフォールバックとセットで使用しましょう。
後に記述したCSSが優先される特徴を利用して以下のように記述すれば多くの場面に対応することができます。
<div style="height: 100vh; height: 100dvh"></div>
Discussion
この日を待っていました!!
一つお伺いしたいのですが、dvhは活用法が思いつきますが、svh, lvhに関しては活用法が思いつきません。現時点でFutaさんが考えているsvh, lvhの具体的な活用法があればお伺いしたいです。
コメントありがとうございます!
svh
,lvh
は使いどころが難しいですよね。例えば、必ず「URLバーが大きい状態」の高さが欲しいときに現状では
vh
を使っています。しかしながら、URLバーの扱いは標準化された仕様で決まっていないので、Safariの現在のバージョンではそう実装されているというだけで将来のバージョンやAndroid Chromeなど別ブラウザでは、変わる可能性があります。
svh
,lvh
を使うことで、環境によらない安定したコードを書くことができるのではないでしょうか。そもそもの使用場面については、はてブのコメントに以下のようなものがありました。
良い情報をありがとうございます。早速仕事で活用しております。
外野からすみません。
svhを早速活用した場面の例として、Webサイトのトップセクションで、画像を画面いっぱいに表示したい、という例がありました。要件としては以下のような感じです。
いままではJSでこねくり回していたので、楽ですねー✨