CSSにViewport単位(Viewport Uints)が導入されてから数年になります。ブラウザーのサイズが変更されるたびに値が変わるという意味で、真にレスポンシブな単位と言えます。Viewport単位について聞いたことはあるものの、詳しいことはまったく分からないという人は、この記事で理解を深めてください。
単位とその意味
CSSにはViewportを基準とした単位が4つあります。vh、vw、vmin、vmaxです。
- Viewport Height(vh):viewportの高さに基づく。1vhはviewportの高さの1%に相当する
- Viewport Width(vw):viewportの幅に基づく。1vwはviewportの幅の1%に相当する
- Viewport Minimum(vmin):viewportの(高さと幅のうち)小さいほうの寸法に基づく。viewportの高さが幅より小さい場合、1vminはviewportの高さの1%に相当する。同様にviewportの幅が高さより小さい場合、1vminはviewportの幅の1%に相当する
- Viewport Maximum(vmax):viewportの(高さと幅のうち)大きいほうの寸法に基づく。viewportの高さが幅より大きい場合、1vmaxはviewportの高さの1%に相当する。同様にviewportの幅が高さより大きい場合、1vmaxはviewportの幅の1%に相当する
Viewportがさまざまな状況でどのような値を取るか説明します。
- viewportの幅が1200px、高さが1000pxの場合、10vwは120px、10vhは100pxとなる。このviewportでは幅のほうが高さより大きいため10vmaxは120px、10vminは100pxとなる
- このデバイスの向きが変わってviewportの幅が1000px、高さが1200pxになると、10vhは120px、10vwは100pxとなる。興味深いことに、10vmaxは大きいほうのviewportの値に基づいて決定されるので120pxのままである。同様に10vminも100pxのままである
- ブラウザーウィンドウのサイズを変更してviewportの幅を1000px、高さを800pxにすると、10vhは80px、10vwは100pxとなる。同様に10vmaxは100px、10vminは80pxとなる
この時点では、Viewport単位は%指定と同じように思えるかもしれません。しかし、Viewport単位と%との間には大きな違いがあります。%指定の場合、子要素の幅や高さは親要素の幅や高さに対して決定されます。以下に例を示します。
見てのとおり、最初の例で子要素の幅は親要素の幅の80%に設定されています。ところが2番目の例では子要素の幅が80vwに設定されているため、子要素の幅が親要素より広くなっています。
Viewport単位の使いどころ
Viewport単位はviewportの寸法を基準としているため、要素の幅、高さ、サイズをviewportに合わせて設定しなければならない状況でとても便利です。
フルスクリーンの背景画像やセクション
フルスクリーン表示される要素に背景画像を設定することはよくあります。製品やサービスに関する個々のセクションが画面いっぱいに表示されるようにWebサイトをデザインしたいと思う場合があるでしょう。そうしたケースでは各要素の幅を100%に、高さを100vhに設定できます。
例として、HTMLを次のようにします。
<div class="fullscreen a">
<p>a<p>
</div>
下のCSSで背景画像をフルスクリーンで表示できます。
.fullscreen {
width: 100%;
height: 100vh;
padding: 40vh;
}
.a {
background: url('path/to/image.jpg') center/cover;
}
ぴったり収まる見出しを作成
jQueryプラグインFitTextについて聞いたり、使ったりした経験があることでしょう。このプラグインを使えば、見出しが親要素の幅いっぱいになるように調整できます。先に述べたようにViewport単位で設定された値はviewportのサイズに直結して変わるので、Viewport単位を使って見出しのfont-sizeを設定すると、画面に見出しをぴったり収められます。viewportの幅が変わるたびに、ブラウザーは見出しのテキストを適切に自動調整します。font-sizeの初期値をViewport単位できちんと設定しさえすれば良いのです。
この方法でfont-sizeを設定する際の主な課題は、テキストサイズがviewportによって異なってしまうことです。たとえば、font-sizeを8vwに設定すると、viewportの幅1200pxに対しては約96px、400pxに対しては33px、1920pxに対しては154pxになります。これでは読みやすさの点でフォントが大きすぎたり小さすぎたりということになりかねません。Viewport単位とcalc()関数の組み合わせを使ってテキストサイズをうまく決定するには、『Viewport Unit Based Typography(Viewportの単位ベースのタイポグラフィ)』が優れていますので参考にしてください。
要素を簡単に中央に配置
Viewport単位は、ユーザー画面の中央に要素を正確に配置する必要がある場合にとても役立ちます。要素の高さが分かっていれば、marginプロパティでtopとbottomの値を[(100 - height)/2]vhに設定するだけで表示できます。
.centered {
width: 60vw;
height: 70vh;
margin: 15vh auto;
}
注意事項
プロジェクトでViewport単位を使う場合、注意点がいくつかあります。
Viewport単位を使って要素の幅を設定するときは慎重にしてください。なぜならルート要素のoverflowプロパティがautoに設定されていると、ブラウザーはスクロールバーが存在しないものと解釈するからです。これによって要素の幅が期待よりわずかに広くなります。次のように、div要素を4つマークアップしてスタイリングすると考えてください。
div {
height: 50vh;
width: 50vw;
float: left;
}
通常、divはそれぞれ画面の可用領域の4分の1を占めると考えられます。しかし、各divの幅はスクロールバーが存在しないものとして計算されるので、横並びの幅が所定の幅よりもいくらか広く表示される結果となります。
幅を50%に設定することでこの問題を解決できます。つまり、スクロールバーがブロック要素の幅の計算に支障をきたさないようにするには、ブロック要素の幅は%で指定したほうが良いのです。
同様の問題はモバイルデバイスでも起きることがあります。ユーザーがスクロールしているかしていないかによって、アドレスバーが表示されたりされなかったりする場合があるからです。このためにviewportの値が変わり、コンテンツを見ているユーザーが急に(画面の)変化を感じることになります。
ブラウザーの対応状況
Can I useのデータによると、主要なブラウザーはどれもViewportに対応しています。とはいえ、いまなおバグや問題がかなりあるので、それを踏まえてViewportを使うことが必要です。たとえばIE9ではvminの代替としてvmを使う必要があり、IE10以降のブラウザーとEdgeはvmaxに対応していません。また、Viewportで寸法を定義した要素はChromeでは出力されません。
Can I useの地域オプションを使ってもう少し詳しく調べてみると、対応ブラウザーを使っている人の割合は地域によって大きな差があることも分かります。たとえばアメリカ合衆国では97.5%の人がViewportに対応したブラウザーを使っています。しかし、この割合はアジアでは73.76%、さらにインドでは45.28%と低くなります。インドで対応ブラウザーを使っている人がこれほど少ないのは、多くの人がデータの保存にUC Browserを使っているためです。こうした情報は、プロジェクトでViewport単位を使うかどうか決定するのに役立つことでしょう。
最後に
この記事ではViewport単位の意味、適用、ブラウザー対応状況について簡単に取り上げました。
この記事をレビューしてくれたDave MaxwellとRalph Masonに感謝します。
(原文:CSS Viewport Units: A Quick Start)
[翻訳:新岡祐佳子/編集:Livit]