【CSS+Javascript】スマホのステータスバーが表示されている状態でブラウザ範囲に全面表示する
お前は何を言ってるんだ
まあ、こう、このようにしたいのです。ファーストビュー全面に収まるように縦横100%のボックスを作り、そのボックス内で縦横中央揃えのテキストを表示するという画面です。なお配色センスはお母さんのお腹の中に置いてきました。
スクロールを前提としない、ダッシュボードのような画面を想定しています。(ちょっと特殊用途ではありますが、「ブックマークから開いたらあとは一切触らない」という想定です)
とりあえず結論だけ
<script>
let view_height = window.innerHeight
document.documentElement.style.setProperty('--vh', view_height/100 + 'px');
</script>
<style>
.main_contents{
height: calc( var(--vh) * 100 );
display: flex;
align-items: center;
justify-content: center;
}
</style>
魔法の単位vhと魔法のプロパティflexboxで、一瞬で実現
んで、まあ、ここまではvhという魔法の単位とflexboxを使うことで非常に簡単に実装できます。テキストサイズの問題はありますが、ボックスの表示に関してはレスポンシブ対応です。
<!-- index.html -->
<!DOCTYPE html>
<html lang="ja" xml:lang="ja">
<meta charset="utf-8">
<head>
<link href="style.css" rel="stylesheet">
</head>
<body>
<div class="main_view">
<div class ="main_contents">
<p>
test<br />
test<br />
test<br />
</p>
</div>
</div>
</body>
htmlはこんな感じでざっくり。main_viewクラスを与えたdivの中に、main_contentsクラスを与えたdivを配置してあります。
// style.css
*{margin:0;padding:0;}
.main_view{
height: 100vh;
background-color: aqua;
display:flex;
justify-content: center;
align-items: center;
}
.main_contents{
height: 100vh;
width:90%;
background-color: burlywood;
display: flex;
align-items: center;
justify-content: center;
}
.main_contents p{
font-size: 10vw;
text-align: center;
}
とにかく縦全画面にしたいブロックのheightを100vhに設定するだけで縦全画面になります。自動的にブラウザのサイズを取得してその数値を入れてくれる神単位です。
main_contentsクラスはわざとwidthを90%にしてあります。ボックスが二つ重なってるぞーってわかりやすくするためです。
後はflexbox使ってmain_viewに対してmain_contentsを縦横中央揃えに、さらにmain_contentsに対して、main_contents内のpタグを縦横中央揃えにしています。(親要素に display: flex; align-items: center; justify-content: center; のプロパティを設定してあげるだけで縦横中央揃えが実現できます。こちらも神。上手く行かないときは親要素子要素それぞれのwidthとheightを指定してみてね)
flexboxについてはこちらのチートシートがわかりやすくまとまっていていつもチラ見しながら作業しています。嘘ですガン見です。首っ引きです。
一部掲載のないプロパティもありますがだいたい事足ります。
さて、画面の縦横比色々変えてみたり、chromeの検証ツールでユーザーエージェント変えてみたりして、でーきた!って思うじゃないですか。
スマホで表示してみるとこうですよ
こう。
スマホ実機で表示するとはみ出す問題
横画面なのは問題点が分かりやすいからです。(縦画面だと、ぱっと見真ん中に表示されてるように見えちゃったので。実際は同様にテキストはずれてるしボックスの下の方ははみ出してるんですけど)
色々調べたら、どうも、スマホのブラウザってほら、ステータスバー(アドレスバー)、あれ、引っ込むじゃないですか。下にスクロールしていくと、スンって上に消えるじゃないですか。あれのせいで、「あっ、ぼくブラウザエリアとは別計算なんで~」つって。
あと、私が使ってる機種は下の、ホームボタンが潜んでるバー、あれもオーバーレイで表示されてるらしくて今回みたいな使い方したいときはくっそ邪魔。(こればかりはどうしようもないので余白を調整して回避)
「vh」って単位はブラウザの縦サイズを基準に計算するんですが、スマホブラウザはご丁寧にステータスバーが消えたときの最大サイズを基準に計算してくれるそうなんですね。HAHAHA。今は有り難くない。(スクロール前提のページなら有り難いんでしょうけども……)
んだけども、じゃあステータスバー分引いたサイズをファーストビューサイズとして計算して…………って思うと、PCで表示したときに崩れちゃう。いやー、めんどーい。
そこで、javascriptを使って実際のブラウザサイズを入手する
let view_height = window.innerHeight
たった一行。
これだけで、ステータスバーを除いた実際の描画エリアのサイズを取得することができますやったね。 もちろん常にステータスバーが表示されているPCでは100vhと同じサイズが取れます。
(スクロール前提の画面作りをする場合、これだとセカンドビュー以降の画面サイズがまた厄介な感じになってきますが、今回は無視出来るので全部これで行きます)
入手したサイズを元にカスタムプロパティを作る
実はCSS3にはオリジナルの定数的なものを設定出来る機能があります。知らなかった。
:root{
--window_height: 100px;
}
みたいに、:rootのスタイルとして「ハイフン2つ+名前:数」を設定してあげることで、上記の例なら「window_height=100px」という単位を設定することが可能です。厳密に言うと2window_heightみたいに使えるわけではないので、単位というか変数みたいな感じ。変更出来ないから定数か。
使う時は
.test{height: var(--window_height)}
のように、var(--名前)と指定してあげれば、
.test{height: 100px}
と指定したときと同じように動きます。
が、取得した画面高さは動的なので、CSSファイルに:rootのプロパティとして書いておくわけには行きません。javascriptに設定してもらいます。
document.documentElement.style.setProperty('--vh', view_height/100 + 'px');
これも1行(view_heightはさっき取得したやつ)。
いちいちwindow_heightとか書くのも大変なので、元の単位に合わせて--vhとしました。100で割っているのは、元々vhを使っていた部分との置換を直感的に行えるようにするためです。
で、CSS側で今まで100vhと指定していた箇所を
height: calc( var(--vh) * 100 );
に置き換えます。画面の高さを100で割って求めた--vhの値をまた100倍しています。100vhとの置換を直感的にするためですので、100しか使わんわ、という場合はview_heightをそのまま何か別の名前の単位として登録しちゃうのもアリですね。
この辺りのやり方はこちらのサイトを参考にさせて頂きました
できたー
できたー
しかし、モダンスマホのファーストビューの縦幅せっまいな……画面自体が縦長だから……
この記事が気に入ったらサポートをしてみませんか?