【CSS】要素の高さを100vhとしたときの問題点とは?3つの解決方法について解説
CSSで要素の高さを100vhと指定したいときがあるかと思います。
この指定は簡単にできる反面、想定通りの表示にならないことも多く、扱いが難しいですよね。
今回は、CSSで要素の高さを100vhと指定しても上手く表示されないという方のために、
- 何故そういう表示になるのか
- どんな解決方法があるのか
以上の項目に沿って、解説していきますね。
この記事を読めば、CSSで100vhと指定したときの問題について、その解決方法が分かるようになりますよ。
ぜひ最後まで読んでくださいね!
100vhとは?100%と何が違う?
そもそも、100vhとはどういう指定なのでしょうか?
vh(viewport height)は、要素のサイズを指定する単位の1つで、100vhはビューポートの高さ全体を示しています。
ビューポート(Viewport)は、ウェブページが表示される領域のことを指します。
具体的には、ユーザーがブラウザでウェブページを見る際に表示される画面の領域を指します。
ビューポートはウィンドウやデバイスに依存し、そのサイズはデバイスやブラウザの設定によって変わります。
ビューポートのサイズは、ウィンドウのサイズやデバイスの画面サイズによって異なります。ウィンドウをリサイズしたり、デバイスの向きを変えたりすると、ビューポートのサイズも変化します。
以下のように指定します。
div {
height: 100vh;
}
これに対して、100%とは親要素の高さいっぱいという指定になります。
親要素のサイズが100%であれば、子要素も画面の高さと等しくなりますが、そうでない場合もあるので注意が必要です。
このほか、要素のサイズはpxやremでも指定できますが、いずれもサイズを固定してしまいます。
レスポンシブサイトのファーストビューで、画面いっぱいのコンテンツを見せたいときなどには、あまり向いていない指定と言えるでしょう。
画面サイズを基準にしたvhは、そんな場面で役立つ単位です。
100vhと指定したときの問題点
vhは、画面の高さを基準に指定するのに便利な単位ですが、ブラウザの状態によって見え方が変わる可能性があり、これが特にサイトを開いたときに最初に目に入るファーストビューに大きな影響を与える問題があります。
2つの問題点を紹介しましょう。解決方法もこの後に紹介しますね。
アドレスバーの幅だけ下に隠れる
ブラウザでWebページを開くと、画面上部にURLが書かれたアドレスバーが表示されます。
これにより、アドレスバーの高さ分、ページ全体が下にずれ込み、画面いっぱいの表示をしたいコンテンツが下の方に隠れてしまいます。
最初からアドレスバーの高さ分の考慮をしてサイズ指定をしようとしても、アドレスバーの高さがブラウザによって異なるなどの問題点があります。
スクロールするとバーが消える場合もあるのですが、その挙動もブラウザによって変わります。
キーボード入力で高さが変化する
文字入力できるフォームの高さにvhを指定している場合には、注意が必要です。
vhが基準とする画面サイズに、キーボード入力の高さは含まれません。
画面のサイズからキーボードの高さ分を引いたサイズが、vhの基準となります。
そのため、入力するキーボードが出てきたときと出ていないときとで、要素の高さが大きく変わってしまいます。
こちらも影響を受けないように指定していきましょう。
100vhの問題点の解決方法
画面のサイズに合わせようとして、「height: 100vh」と指定しても、想定通りの表示にならない場合があることが分かりましたね。
前述のような問題が起きないように、どう対策するのが良いのでしょうか?
ここでは、3つの解決方法を紹介します。
- 100%を使う方法
- iOSのみの解決方法
- JavaScriptを使う方法
それぞれ説明していきますね。
100%を使う方法
1つ目は100%で代用することです。
<body>
<header>
<div class="sample"></div>
</header>
</body>
CSSは、以下のように記述します。
*{
padding: 0;
margin: 0;
box-sizing: border-box;
}
html, body, header,.sample {
height: 100%;
}
.sample{
background: #ccc;
}
「height: 100%」は、親要素を基準に100%ということなので、html, body, headerなども100%に指定しなくてはいけません。
この指定で、灰色の要素が画面いっぱいに表示されるのを確認できたでしょうか。
ファーストビューで画面いっぱいのコンテンツを見せたい場合には、この方法が有効です。
ただし、ブラウザによっては、アドレスバーが消えた瞬間にアドレスバーの高さだけページ全体が上に移動し、下の隠れていた他の部分が見えることがあります。
その間は、要素の高さは100%のサイズからアドレスバーの高さ分を引いたものとなるので、そこが気になる方は、別の方法を試してみてください。
iOSのみの解決方法
スマホの中でも、iPhoneの表示を何とかしたい、というときに使える方法です。
iPhone以外にもiPadなど、iOSを利用している端末に利用できます。
<div class="sample"></div>
CSSは以下のように記述します。
*{
padding: 0;
margin: 0;
box-sizing: border-box;
}
.sample{
height: 100vh;
background: #ccc;
}
@supports(-webkit-touch-callout: none){
/* iPhoneの表示のみ指定を上書き */
.sample{
height: -webkit-fill-available;
}
}
「@supports(){」の中で上書きする指定を書いています。
この指定は、iOSのsafari、Chromeで機能しますが、それ以外のブラウザでは「height: 100vh」が適用されます。
また、「-webkit-fill-available」は、デスクトップ版のChromeにも適用されます。
デスクトップ版で適用されてしまうと、表示が崩れることがあるので、以下の記述を行い、デスクトップ版では動作しないようにしています。
@supports(-webkit-touch-callout: none)
JavaScriptを使う方法
最後に、JavaScriptを使う方法を紹介します。
どのブラウザでも期待通りの表示をしてくれるので、この方法が一番おすすめです。
CSSは以下のように記述します。
*{
padding: 0;
margin: 0;
box-sizing: border-box;
}
.sample {
height: 100vh;
height: calc(var(--vh, 1vh) * 100);
background:#ccc;
}
「–vh」の部分をJavaScriptを使って取得します。
let vh = window.innerHeight * 0.01;
document.documentElement.style.setProperty('--vh', `${vh}px`);
window.innerHeightは、ウィンドウのビュー全体の高さを取得します。
ここでは、1vhの高さを取得したいので、0.01倍し、変数vhに代入します。
2行目のsetProperty()で、変数「–vh」に、「${vh}px」を代入しています。
この第二引数の記述は、テンプレートリテラルという表記法で、演算子を使わずに文字列を繋げることができます。
囲っている記号「`」はバッククォートといい、第一引数で用いているシングルクォートとは異なるので、間違えないようにしましょう。
clac()とvar()の機能と使い方について詳しく説明していきます。
clac()とは?
clac()は、CSSの中で四則演算ができる関数です。
プロパティの値を計算結果で指定することができます。
pxだけでなく、%やemなどでも計算を行います。単位が揃っていなくても計算可能です。
.sample{
width: calc(100% - 50px);
}
上記では、横幅いっぱいから50px引いた値がwidthに指定されますね。
演算子の前後には、半角スペースを入れる必要があります。
var()とは?
var()は、CSSの中で変数を扱える関数です。
例えば、以下のように「:root」で変数を指定すると、<html>内のすべての要素にその指定ができるようになります。
:root {
--color-main: pink;
}
.sample {
background: var(--color-main);
}
.box-txt{
color: var(--color-main);
}
色を変えたいときには、一番上の「–color-main: pink」の指定を変えるだけで、すべてに適用されます。
この変数は「CSSカスタムプロパティ」と呼ばれ、冒頭に2つのハイフンを入れることが慣習になっています。
変数を利用することで、JavaScriptで計算することもできるようになります。
var(--color-main, red)
上記のように、第二引数を指定することもできます。
第一引数が定義されなかったときに、第二引数が使用されます。
画面サイズが変わったときに高さを更新する方法
すべてのブラウザに対応する方法を紹介しましたね。
ただし、このままでは縦から横、横から縦にデバイスの画面が変わったときに、要素の高さは変化しません。
画面の高さが変わるたびに、要素の高さも変わるようにするには、どうすれば良いのでしょうか。
JavaScriptを以下のように書き直してみてください。
window.addEventListener('resize', () => {
let vh = window.innerHeight * 0.01;
document.documentElement.style.setProperty('--vh', `${vh}px`);
});
上記のように「resize」を使うことで、windowのresizeイベントを取得するたびに、高さを計算して求めてくれるようになります。
これにより、デバイスの向きを変えたときにも画面の高さいっぱいに要素が表示されます。
他の部分のコードは一緒です。
まとめ:要件によって使い分けよう
今回は、CSSで要素の高さを100vhと指定したときに、PCでもスマホでも期待通りの表示にする方法を解説してきました。
CSSで完結する方法から、JavaScriptを使う方法まで紹介しましたね。
様々な環境に対応するならJavaScriptがおすすめですが、要件によってはCSSで対応する必要が出てきます。
柔軟に対応できるように覚えておきましょう。
CSSで要素を画面の高さいっぱいに表示させたいときに、今回の記事が参考になれば幸いです。