vwとremを組み合わせて、アスペクト比を維持したサイズ可変レイアウトを実装する


un-T factory! XA Advent Calendar 10日目の記事です。

リキッドレイアウトの葛藤

リキッドレイアウトによるWebページ制作の際、表示端末の画面幅(viewport)の違いによって各要素のサイズ比率が変わり、デザイン時の意図と異なる見た目になってしまうことがあります。

特にスマートフォンやタブレットでは端末によってブラウザ幅が固定されるため、テキストの改行のされ方や周辺要素とのレイアウトバランスなど、ちょっとした違いでページの印象が大きく変わることもあります。

「さまざまな解像度の端末があるのだから、そのような違いが出ることも許容するべき」という考え方にはもちろん同意ですが、今回は、CSSのサイズ指定を少し工夫してアスペクト比を維持したサイズ可変レイアウトを手軽に実装する方法を紹介します。

サイズ可変レイアウトの実装

一つの例として、画面幅(viewport)が320px〜480pxの範囲で、アスペクト比を維持したままページ内コンテンツのサイズを変化させる場合を考えます。

なお、基準となるデザインカンプは320px幅で作成されているものとします。

実装イメージ

画面幅を変更した場合も、ページ内コンテンツは比率を保ったまま拡大縮小し、テキストの改行位置も維持されています。

vwとremによるfont-size指定

CSS
@media screen and (min-width: 320px) and (max-width: 480px) {
  html {
    font-size: 3.125vw;
    /*
      計算式: 10(px) / 320(px) * 100 = 3.125
      画面幅320pxの時に "font-size: 10px" 相当になる
    */
  }

  body {
    font-size: 1.6rem;
    /*
      html要素で指定されたfont-sizeの1.6倍になる
    */
  }
}

サイズ計算をしやすくするため、まずはhtml要素に対して font-size: 3.125vw を指定します。
vw画面幅を基準とした相対サイズ単位であるため、画面幅が320pxの時には font-size: 10px 相当になります。

次にbody要素に対して font-size: 1.6rem を指定してみましょう。
remhtml要素(ルート要素)の font-size を基準とした相対サイズ単位であるため、結果的にbody要素内のテキストは、画面幅が320pxの時に font-size: 16px 相当になります。

また、テキストサイズの基準値を vw で指定しているため、例えば画面幅が320px→384px(1.2倍)に広がった場合はテキストサイズも同様に1.2倍に(同じ比率で)拡大されます。

画面幅 倍率 html要素のfont-size(=1rem) body要素のfont-size
320px (1) 10px 相当 16px 相当
360px 1.125 11.25px 相当 18px 相当
384px 1.2 12px 相当 19.2px 相当
400px 1.25 12.5px 相当 20px 相当
480px 1.5 15px 相当 24px 相当

このようにして、画面幅320px〜480pxの範囲内で、テキストサイズが画面幅に応じてスムーズに変化する仕組みを作ることができました。

レイアウトに関するサイズ指定をすべてremにする

rem によるサイズ指定は font-size 以外のプロパティに対しても有効です。

レイアウトに関するさまざまな数値(width, height, margin, padding など)を rem で指定することで、画面幅に応じて、アスペクト比を維持したまま各要素のサイズを変化させることが可能になります。

320px幅で作成されたデザインカンプを見ながら、各要素のサイズをCSSに落とし込みます。

前述の通りhtml要素(ルート要素)のテキストサイズ(=1rem)は画面幅320pxの時に font-size: 10px 相当になっています。

よって、320px幅のデザインカンプ上における10pxを、CSS側で 1rem として(10分の1にして)指定していくと、カンプ通りのレイアウトを再現できることになります。

カンプ上のサイズ CSSの指定値
5px 0.5rem
10px 1rem
100px 10rem
CSS
/* サイズに関する記述を抜粋 */

header {
  font-size: 2.2rem;
}

.content {
  padding: 2rem 2rem;
}

figure {
  position: relative;
}

figcaption {
  position: absolute;
  bottom: 1.6rem;
  left: 1.6rem;
  font-size: 1.4rem;
}

.lead {
  margin-top: 1.4rem;
  font-size: 1.2rem;
}

サイズに関する数値をすべて rem で指定しています。

画面幅を 320px〜480px の間で変化させた場合も、各要素がアスペクト比を維持したまま拡大縮小し、レイアウトバランスが保たれます。

px指定との併用も可能

画面幅にかかわらずサイズを固定したいプロパティに対しては、rem ではなく px による指定をすればOKです。

例えばあるレイアウトブロックをサイズ可変にしつつ、境界線(border)は1px幅のままで固定したい場合は、次のように rempx を併用することで実現できます。

CSS
.sample-block {
  margin: 3rem;
  padding: 2rem;
  border: 1px solid red; /* border幅のみpxで指定 */
}

注意点

この設計手法は、html要素の font-sizevw で指定することが大前提となります。
何らかの理由でhtml要素のスタイルを変更できない場合は、各レイアウトパーツごとに個別に vw 値を計算して指定していく方法を検討しましょう。

参考リンク

length #vw | MDN
font-size #rem | MDN