【CSS】vhは一画面でない...ならばwindow.outerHeightを試してみよう+実用例
こんにちは!今日は 前回の続き、曲者のCSSの単位「vh」を扱いやすくするテクニックについて解説します。
100vhは一画面じゃない
前回は100vhがぴったり一画面じゃないという話を長々としました。ざっくり言うと、スマホでの閲覧ではメニューバーやキーボードに対しvhの相性が悪いってことですね!
逆に言えば画面の高さではなくコンテンツが表示されている部分の高さが分かれば問題ないってことですね!。
ならばwindow.outerHeightだ
outerHeightはwindowのメソッドの一つで、vhの画面の高さとは違って画面のうちコンテンツが表示される部分の高さを取得するメソッドです。
アドレスバーやキーボードは画面に表示されますが、実際のWebサイトを表示する部分ではないですね!つまり、outerHeightはこれらを含みません。
outerHeightの値はブラウザをリサイズしない限りは変わりません。スマホにおいてはほぼ不変であると言えるのではないでしょうか?
一方、ブラウザのリサイズを考慮する必要のあるPCにおいてはvhで十分でしょう。
簡単な実用例
以下のdivを例に考えてみます。heightが100vhになっている.first-viewを window.outerHeightで上書きすることでdiv要素の高さを変更してみます。
<div class="first-view"></div>
.first-view {
height: 100vh;
}
document.addEventListener('DOMContentLoaded', () => {
document.querySelectorAll('first-view').style.height =
`${window.outerHeight}px`
})
これにもう少し足して、PCならvh、スマホならouterHeightを代入するようにしてみましょう!
少し前の記事で書いた、PCかスマホかを見分けるワンライナーを使ってみます。
document.addEventListener('DOMContentLoaded', () =>{
/iPhone|iPod|iPad|Android/i.test(navigator.userAgent)
&& document.querySelectorAll('first-view')
.style.height = `${window.outerHeight}px`
})
もう少し高度な実用例
↑の例は少し密結合すぎるので、CSS変数を使ってもっと本格的に実装してみます。
まずは高さの部分をCSS変数**—outer-height**に定義します。この時点では—outer-heightの値は100vhです。
<div class="first-view"></div>
:root {
--outer-height: 100vh;
}
.first-view {
height: var(--outer-height);
}
この状態で↑と同じくスマホなら—outer-heightを更新します。PCならそのままです。
コードはこのような感じでしょうか?
document.addEventListener('DOMContentLoaded', () => {
;/iPhone|iPod|iPad|Android/i.test(navigator.userAgent) &&
document.documentElement.style.setProperty(
'--outer-height',
`${window.outerHeight}px`,
)
})
もう少し分解して分かりやすく書くとこうなります。
// DOMの読み込みが完了したらsetOuterHeightが発火
document.addEventListener('DOMContentLoaded', setOuterHeight)
// スマホならtrue, PCならfalse
const isSP = /iPhone|iPod|iPad|Android/i.test(navigator.userAgent)
// 端末の種類をもとにCSS変数を定義
const setOuterHeight = () => {
// 端末がスマホなら
if (isSP) {
// CSS変数 --outer-height に outerHeight px を代入
document.documentElement.style.setProperty(
'--outer-height',
`${window.outerHeight}px`,
)
}
}
こうすればCSS変数—outer-heightはwindows.outerHeightと同値となり、 各々のコンポーネントで使いまわせます。下はそれぞれ100vh,50vh,30vh相当の 3つのdiv要素の記述例です。
<div class="first-view"></div>
<div class="second-view"></div>
<div class="third-view"></div>
:root {
--outer-height: 100vh;
}
.first-view {
height: var(--outer-height);
}
.second-view {
height: calc(var(--outer-height) * 0.5);
}
.third-view {
height: calc(var(--outer-height) * 0.3);
}
だいぶ便利になりました :) CSS変数やsetProperty周りはうまく設定すればJS-CSS間で値を共通化できたりしてとても便利!ぜひご活用ください。後日、CSS変数関連でもう1記事書く予定です。