Responsive font sizeに(今更)チャレンジ

今まで避けて通ってきたResponsive font sizeを使ってみました。とゆーのも、縦書きデザインのコーディングをすることになって、画面サイズとフォントサイズが連動したほうが都合が良さそうだったので。

Responsive font sizeをインポートして使ってみる

筆者が最初にResponsive font sizeを使用しようと思ったのは、Bootstrapのドキュメント内に言及されている箇所を見たとき。ファイルサイズが肥大するため、筆者自身はBootstrapはあまり使いたくないのですが、Bootstrap最高\(^O^)/と思っているフシのあるパートナーさんに、使用するよう指示された案件に関わっていた時のことです。

件の記述を読んでみると、Bootstrapで使われている見出しのclassがResponsive font sizeに対応しており、Responsive font size用のファイルを別途インポートすれば使えるとの記述がありました。

まずはnpmでインストールして、

npm install rfs

bootstrapを読み込む前にインポートします。

@import "node_modules/rfs/scss";
@import "node_modules/bootstrap/scss/bootstrap";

勿論、Responsive font size単体でも使うことはできて、Sass、Less、Stylus等のCSSプリプロセッサとともに利用できるようです。

独自のSCSS用mixinを作ってみる

さて、次にResponsive font size導入を検討したのは、縦書き案件に遭遇した際のことです。
縦書きにすると、ブラウザによって解釈がまちまちで、なんかヤな感じですね…。いっそ、デザインカンプ作成ツールの全てで縦書きが扱えなければいいのに、と、デザインにあまり関心のない筆者は思ったりしたのですが、Adobe XDはまだ縦書き対応していないようですね(プラグインで擬似的に対応できるみたい)。頻繁にアップデートされているので、そのうち対応されてしまうのではないかと危惧しています。

そんなことはともかく、件の案件では、画面幅に広がっている画像の中に、ページタイトルが縦書きで入っており、すなわち画面幅に従って高さが増減するコンテナ内に縦書き文字を収めなければならない、というものでした。
普段は横着して、768pxをブレイクポイントとし、2種類の文字サイズしか設定しないことが多いのです。が、この案件ではそういう横着はやめたほうが良さそう、ということで、独自のmixinを作ってみることにしました。

といっても、先人の知恵をお借りしますよ。
シンプルでわかりやすかったのが、こちらのcode pen

デフォルトのブレイクポイントが2箇所設定してあり(変更も可能)、フォントサイズの最小値と最大値を指定すれば、ブレイクポイントの間でフォントサイズが増減するようになっています。
大変良くできていますが、コレをこのまま使うとちょっと不都合があったため、メディアクエリの記述を省いた状態で利用することにしました。

mixinの設定として次のように書き、

//Responsive font size
@mixin rfs($fs,$fs-l,$vp,$vp-l) {
  font-size: calc(#{$fs} + ((100vw - #{$vp} ) * ( #{num($fs-l)} - #{num($fs)} ) / ( #{num($vp-l)} - #{num($vp)} ) ));
}

//strip units helper function 変数から単位を削除して数値のみにする関数よ。頭いいですねー(゚д゚)!
@function num($input){
  @return $input/($input * 0 + 1);
}

//break point
$bk_md:768px;
$bk_xl:1200px;

//media query
@mixin mq {
  @media only screen and (min-width: $bk_md) {
    @content;
  }
}
@mixin mq_xl {
  @media only screen and (min-width: $bk_xl) {
    @content;
  }
}

SCSSファイルでは最小値と最大値のフォントサイズを指定します。
フォントサイズとビューポートサイズの単位はpx以外のものも使用できます。

.c-title {
    font-size: 24px;
    @include mq {
    @include rfs(24px,48px,$bk_md,$bk_xl);
    }
    @include mq_xl {
        font-size: 48px;
    }
}

コレがコンパイルされたCSSファイル

.c-title {
  font-size: 24px;
}

@media only screen and (min-width: 768px) {
  .c-title {
    font-size: calc(24px + ((100vw - 768px ) * ( 48 - 24 ) / ( 1200 - 768 ) ));
  }
}

@media only screen and (min-width: 1200px) {
  .c-title {
    font-size: 48px;
  }
}

複雑な式ですが、分解すると理解しやすいです。式の後半の部分から見てみましょう。

( 48 - 24 ) / ( 1200 - 768 )

ここでは、フォントサイズの最大値と最小値の差(の絶対値)を、ビューポートサイズの最大値と最小値の差(の絶対値)で割っています。そうすると、例えばビューポートの単位がpxの場合は、1px画面サイズが大きくなるごとにフォントサイズを何px大きくすればよいのかがわかります。
フォントサイズの差は24px、ビューポートサイズの差は432px。

24/432=0.0555....

1px画面サイズが大きくなるごとにフォントサイズを0.0555…px大きくしていけば良いようです。

次に、現在のビューポートサイズ(=100vw)と最小ビューポートサイズの差を出します。

(100vw - 768px )

この値が「最小ビューポートサイズより何px大きいか」を示すことになるので、先程のフォントサイズにこの値をかけてやれば、追加するべきフォントサイズが算出できます。

(100vw - 768px ) * 0.0555...

それをフォントサイズの最小値に足し合わせれば、求めるフォントサイズとなるわけです。

24px + (100vw - 768px ) * 0.0555...

この手法は、フォントサイズのみならず、line-height等、他のプロパティにも応用できそうです。
Responsive font size、どんとこい\(^O^)/
しかし、縦書きCSSは、あんまり使いたくないな…