見出し画像

rem と vw で画面幅に対して常に可変な要素サイズを指定するCSSの書き方

noteエンジニアチーム【公式note】

フロントエンドチームとデザインチームを兼任している uto-usui です🐈

今回は rem の基準となる html 要素のフォントサイズを vw を使った calc() 関数で指定することで、レスポンシブタイポグラフィをやってみて、fluid responsive(画面幅に対して常に可変)な要素サイズ指定をやってみようという話をします。

この手法では、ビューポートが広がったり狭くなってもレイアウトバランスを保ったまま、それぞれのオブジェクトが拡縮してくれます。 実際に採用されているサイトを見てもらうとイメージがつかめるかと思います。

rem と vw で fluid responsive

rem と vw は相対的な単位で、rem はルート要素 html のフォントサイズに連動し、vw はビューポートの幅に連動します。

基準となる html に ビューポート基準の vw 単位でフォントサイズを指定すると、テキストサイズや要素サイズや余白や位置などに rem 単位を使った要素がビューポート幅と連動するようになります。フォントサイズに関連したrem 単位を、別なサイズ表現のプロパティに与えられるCSSのおもしろいところを利用します。

html {
  // viewport 375px のとき font-size 16px
  font-size: calc(100vw * 16 / 375);
}

.ex-object {
  margin: 1rem;
  font-size: 1rem;
  transform: translate(1rem);
}

このように calc() を書くと、ビューポート幅が 375px のときフォントサイズが 16px = 1rem になり、それを基準に連動して拡縮します。

ブレイクポイントを設置して詳細に

ブレイクポイントを設定して基準を変更することで、大きくなりすぎた(小さくなりすぎた)値を整えてみてもよいでしょう。

html {
  // viewport 375px のとき font-size 16px
  font-size: calc(100vw * 16 / 375);
  
  @media (min-width: 768px) {
    // viewport 768px のとき font-size 16px
    font-size: calc(100vw * 16 / 768);
  }
  
  @media (min-width: 1240px) {
    // viewport 1240px のとき font-size 18px
    font-size: calc(100vw * 18 / 1240);
  }
  
  @media (min-width: 1440px) {
    // viewport 1440px のとき font-size 20px
    font-size: calc(100vw * 20 / 1440);
  }
}

fluid responsive では、レイアウトのバランスをウィンドサイズが変わっても保証できるので、カンプデザインのパターンが少ないときのレスポンシブ対応など、さくっと悩まずできてしまうのがよいなあと思います。ただし、それぞれのオブジェクトが狙った以上に大きくなる(小さくなる)ことがあるので、ミニマルな静かなデザインには相性が悪かったりします。

バランスなど考慮しつつブレイクポイントを打って、じぶんのポートフォリオでも採用してみました。

vw ですべてを指定する

また、このように rem の基準値で一括で変更できるようにコントロールする手法とは別に、それぞれの要素すべてに vw を指定する方法もあります。この場合は Sass で関数を用意しておいて一括でコントロールするなど工夫すれば、同じような使用感になると思います。

次のサイトではそのような実装で美しいレイアウトを保証しています。

最小最大を指定する clamp()

またレスポンシブタイポグラフィの取り扱いとして、ブレイクポイントでコントロールする他に、clamp() 関数で最小値と最大値を指定する方法もあります。

.ex-object {
  // clamp(minimum, preferred, maximum)
  font-size: clamp(14px, 5vw, 24px);
}

この場合は、最小と最大がどこかで固定されて vw のビューポート連動から外れてしまうので、レイアウト全般に使うことは厳しいです。シンプルにフォントサイズだけをビューポートに連動させつつ可読性を確保したり、相互のバランス崩れを許容できるオブジェクトに使うとよいかなと思います。

clamp() を使って2点間のフォントサイズを綺麗にレスポンシブさせるには、次の記事に詳しい考察があります。

また、👆🏻こちらで紹介された方法を元にしつつ、美しくスケールさせてくれるジェネレータも紹介しておきます。

レスポンシブタイポグラフィの副作用

注意点として、このようなレスポンシブタイポグラフィを使った手法ではブラウザズームとの副作用があるので、慎重にテストしたり使用は限定的であるべき。次の記事でとても詳細に説明されています。

ブラウザズームを考慮したい場合は次のように、

html {
  font-size: 100%;
  
  @media (min-width: 375px) {
    // 一般的に 100% = 16px
    // そこに vw な値を足す
    font-size: calc(100% + 100vw + 2 / 375);
  }
}

p {
 font-size: 1rem;
}

基準を % で作って vw を付加的に利用してあげるとよいでしょう。テキスト中心のコンテンツ部分などに採用すると、広い画面での可読性を味付け程度に補正して読みやすくなることが期待できます。

さいごに

先に述べたように使用は限定的にしておくのが望ましいですが、ぼくは過去に採用した実績でいうと、画角は決まっているけれど解像度はわからないサイネージの制作で、とても助かったことがありました。

このように突き詰めていくとかなりマニアックな世界、CSSの相対的な単位は奥が深く扱いづらい部分もあるけれど、理解していくととてもおもしろいです。とくにビューポート基準の単位はマルチデバイスな対応によく効いてくれるので、未知の画面環境を多少でも保証できるところがありがたいですね。

それでは以上でおわりです。
読んでいただきありがとうございました。


みんなにも読んでほしいですか?

オススメした記事はフォロワーのタイムラインに表示されます!
noteエンジニアチーム【公式note】
note社エンジニアの公式noteです。noteで活用している技術やさまざまなトライ、エンジニアの活動や働く環境などを紹介していきます