[CSS]ビューポート(vw, vh)とパーセント(%)、レスポンシブに適した単位の賢い使い分け方法
Post on:2015年7月22日
先日の記事「フォントサイズの指定方法(翻訳版)」で、CSSの比較的新しい単位「ビューポートの単位(Viewport Units)」について触れました。この単位「vw, vh, vmin, vmax」はブラウザのビューポートのサイズに基づくもので、これらの単位で指定した実際の大きさはビューポートの大きさによって変化するため、レスポンシブデザインにあった単位と言えるでしょう。
これらの単位を使うことは「フォントサイズの指定方法」でフォントサイズに使うことを反対しましたが、レイアウトでは非常に役立つ単位です。
下記は各ポイントを意訳したものです。
※当ブログでの翻訳記事は、元サイト様に許可を得て翻訳しています。
ビューポートの単位(Viewport Units)とは
ビューポートの単位は相対的な単位で、それ自身が客観的な大きさを持っていないことを意味し、ビューポートのサイズによって決定されます。ビューポートと関係がある単位は、4種類です。
- vw
- ビューポートの幅の1/100
- vh
- ビューポートの高さの1/100
- vmin
- ビューポートの幅か高さの値が小さい方の1/100
- vmax
- ビューポートの幅か高さの値が大きい方の1/100
これら4種類の単位の中で使い勝手がよい最初の2つ(vw, vh)にフォーカスします。多くのケースでこのビューポートを使った単位とパーセントを使った単位は似ていますが、それぞれ明確な長所と短所を持っています。
簡単に言うと、幅を扱う時は「%」、高さを扱う時は「vh」の方が適切です。
要素を幅いっぱいに指定 (% > vw)
「vw」はビューポートの幅に基づいてそのサイズを決定します。このビューポートの幅というのは、ブラウザのスクロールバーを含んだサイズで計算されます。
ビューポートの幅とコンテンツの幅
もしページが長く、スクロールバーが表示されているのであれば、ビューポートの幅はhtml要素の幅より大きくなります。
ビューポート > html > body
そのため、もし要素に「100vw」を設定すると、その要素はhtmlとbodyより大きいサイズになってしまいます。下記の例では、html要素の周りにレッドのボーダー、セクションには背景を設定しました。
要素をページの幅いっぱいにする時は、ビューポートで幅を指定するより、パーセントを使用する方が良いでしょう。
要素を高さいっぱいに指定 (vh > %)
要素をページの高さいっぱいにする時は、パーセントよりビューポートの単位「vh」が適しています。
パーセントで定義された要素のサイズは親要素に基づくため、親要素が高さに何らかの影響を受けている必要があります。これを実現するには、html要素を親要素として要素を配置するか、なんらかのハックをしなければできないでしょう
しかし、「vh」を使用すると簡単にできます。
1 2 3 |
.example { height: 100vh; } |
「.example」要素はどこに配置しても(親要素が何であっても)、ビューポートに比較してサイズが決定されます。スクロールバーの問題はたいていのページは横スクロールがないので問題ないでしょう。
「vh」を使ってどのようにデザインに適用するか例を見てみましょう。
フルスクリーンの背景イメージ
「vh」を使った代表的な用途が、デバイスのサイズにかかわらずスクリーンの高さと幅いっぱいに背景イメージを表示する方法です。これは「vh」を使うと簡単に実装できます。
1 2 3 4 5 6 |
.bg { position: relative; background: url('bg.jpg') center/cover; width: 100%; height: 100vh; } |
フルスクリーンのセクション
同様にページのそれぞれのセクションをビューポートの高さと幅いっぱいに表示させることも簡単です。
1 2 3 4 |
section { width: 100%; height: 100vh; } |
JavaScriptを使用すると、ページをぱらぱらめくるようなエフェクトを与えることもできます。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
$('nav').on('click', function() { if ( $(this).hasClass('down') ) { var movePos = $(window).scrollTop() + $(window).height(); } if ( $(this).hasClass('up') ) { var movePos = $(window).scrollTop() - $(window).height(); } $('html, body').animate({ scrollTop: movePos }, 1000); }) |
画像サイズの最適化
「vh」は画像サイズをコントロールするために使用することもできます。例えば、画像をスクリーンのサイズにかかわらず常に全部が見えるように設定することもできます。
1 2 3 4 5 6 7 |
img { width: auto; /* Image width adjust to height to remain proportional */ max-width: 100%; /* Image doesn't exceed parent element's width */ max-height: 90vh; /* Image doesn't exceed viewport height */ margin: 2rem auto; } |
各ブラウザのサポート状況
ビューポート ユニットは比較的新しい単位のため、いくつかのブラウザに若干の問題がありますが、それらを解決するソリューションもあります。
- iOS Safari 7.1
- 問題: 「vh」周りのバグ
- 解決: Media Queriesを使用して特定のデバイスをターゲットにする。
- 参考: VH and VW units can cause issues on iOS devices
- Opera Mini 8, IE 8
- 問題: 非サポート
- 解決: pburtchaellの解決方法を使用してください。
- 参考: VH and VW units can cause issues on iOS devices
- IE 9
- 問題: 「vmin」の代わりに「vm」をサポート
- 解決: 指定する時に「vmin」「vm」両方の単位を使用する。
- IE 10-Edge
- 問題: 「vmax」は非サポート
- 解決: pburtchaellの解決方法を使用してください。
- 参考: VH and VW units can cause issues on iOS devices
参考
sponsors