31
15

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【CSS】フォントサイズを横幅ぴったりに合わせるfit-widthの提案

Posted at

安いゲームの日本語訳とかで、テキストが画面枠をはみ出て見切れるという何も考えてない実装をよく見かけますよね。

それよりは見えるだけまだマシなものとして、文字数が多くなると画面幅に合わせてフォントサイズが小さくなるという実装もたまに見かけます。

01.jpg
ねとらぼより拝借

この後者、これまでCSS単体では不可能でJavaScriptをがりがり書く必要があったのですが、CSSだけでできるようにする提案がGoogleから出されていました。

ということで以下はCSS fit-width textの紹介です。
まだまだ懸念が残っているようなので、すぐ実装されるというわけでもなさそうですが、実装されるのが待ち遠しいCSSのひとつですね。

CSS fit-width text Explainer

Introduction

テキストレイアウトにおいて、行をコンテナの両端に揃える際、幅を調節するのではなくフォントサイズを調節することでそれを実現したいとします。
現在CSSにはそのような機能がなく、手動で試行錯誤するか、JavaScriptでサイズを変更するしかありません。

Web製作者は、テキストをオーバーフローすることなく特定サイズのコンテナに収めたいと考えます。
たとえばコンテナが狭く、単語が長い場合、フォントサイズを小さくしてでもコンテナ内に収めたくなります。
自動翻訳で予期せず長い単語が選ばれた場合、ユーザが任意入力で長い単語を入れた場合でも、コンテナからはみ出させたくありません。

Why CSS?

なぜCSS?

複雑で問題になりやすいスクリプトから、高性能で使いやすいCSSのソリューションにステージを引き上げます。

Performance

JavaScriptによるソリューションは、要素の大きさの読み取り、新しいスタイルの計算、新しいスタイルの書き込みという手順を踏みます。
動的コンテンツやウィンドウサイズ変更などによってサイクルが頻繁に呼び出されると、レイアウトスラッシングが発生し、画面描写が遅くなったりCPUの負荷を引き起こす可能性があります。

ネイティブCSS実装では、フォントサイズの計算を既存のレンダリングパイプラインに直接統合することができます。
JavaScriptによるオーバーヘッドや呼び出しタイミングの影響を受けることなく、効率的にフィッティングが行われます。

Improved User Experience

JavaScript実装では、最初に一定サイズでテキストが描画された後で動的にサイズ変更されるため、テキストがちらついたり動いたり、リフローが発生することがよくあります。
CSSネイティブのプロパティにすることで、最初の描画までに最終的な位置とサイズが決定され、テキストは最初から正しい位置に正しいサイズで描画されることになります。
よりスムーズなユーザエクスペリエンスが提供され、First Contentful Paintも向上します。

Simplified Authoring & Maintainability

JavaScriptで堅牢なテキストフィッティングを実現するには複雑な処理が必要となります。

CSSを用いれば、開発者はシンプルにプロパティ宣言するだけでいいので、テストや保守のコストを大幅に削減できます。

Goals

目的。

テキストの大きさをコンテナの幅に合わせる。
テキストの拡大縮小、両方に対応する。

Non-goals

目的でない。

・コンテナの幅を調整する。
・テキストの大きさを、コンテナの幅と高さ両方に合わせる。
・行を折り返す。

Use cases

ユースケース。

ニュースサイト、ブログ、マガジン、ポートフォリオなどには、様々なレイアウトや画面サイズに対応する、柔軟で魅力的なタイポグラフィが必要不可欠です。
本機能は、特にレスポンシブな見出しにおいて役立ちます。
具体的には以下のような例が挙げられるでしょう。

Expanding

拡大。

重要な記事の短い見出しは、幅の広い列では埋もれてしまいます。
本提案では、幅に合わせてサイズや文字数・単語間隔を自動的に調整し、手動調整もJavaScriptもなしに強い視覚効果を生み出します。

・オリジナル

11.png

・A:コンテナの幅に合わせて行ごとに拡大

12.png

・B:最も長い行がコンテナの幅に合うようにサイズを揃えて拡大

13.png

Shrinking

縮小。

長い単語は、小さな画面や幅の狭いサイドバーではコンテナからはみ出してしまうことがあります。
割り当てられた幅にテキストを縮小するか、間隔を調整することで、文字の途切れや不自然な改行を防止します。

・オリジナル

21.png

・A:コンテナの幅に合わせて行ごとに縮小

22.png

・B:最も長い行がコンテナ内に収まるようにサイズを揃えて縮小

23.png

Combining behaviors

組み合わせ。

両機能を合わせることで、コンテナの幅を常に100%専用する見出しを作成することができ、コンテナの幅を変更しても自動的に追随します。
デザインに合わせて自然にテキストが調整されるレスポンシブレイアウトを作成できます。

・オリジナル

31.png

・A:コンテナの幅に合わせてサイズを行ごとに調整

32.png

・B:コンテナの幅に合わせて文字間隔を行ごとに調整

33.png

・C:コンテナの幅に合わせて横幅を行ごとに調整

34.png

・D:コンテナの幅に合わせて間隔と横幅を行ごとに調整

35.png

Fitting Captions and Pull Quotes

画像の解説テキストや引用文のテキストは、関連するコンテンツの幅にぴったり収まるようにする必要があります。
はみ出ることを縮小で防ぎ、キャプションが短すぎて不自然になることを防ぐために拡大します。

Aligning Text Blocks

短いテキストブロックをコンテナの端に揃えるため、スペースやサイズを微調整したいことがあります。
そんなときに、両端揃えテキストを使うと生じる大きすぎる文字の隙間を防ぐことができます。

[Potential Solution]

2つのCSSプロパティを追加します。

text-grow

プロパティのフォーマットは<fit-target> <fit-method>? <length>?

text-shrink

プロパティのフォーマットは<fit-target> <fit-method>? <length>?

・プロパティfit-target

値はnoneconsistentper-line
per-lineはコンテナ内の各行を個別に拡大縮小する。
consistentはコンテナ内の全ての行を、最も長い行と揃えて拡大縮小する。

・プロパティfit-method

値はscalescale-inlinefont-sizeletter-spacing
scaleはフォントサイズはそのままグリフを拡大縮小する。
scale-inlineはフォントサイズはそのままグリフを水平方向にのみ拡大縮小する。
font-sizeはフォントサイズを変更し、グリフを再計算する。
letter-spacingは文字間隔で調整する。

・プロパティlength

text-growの最大フォントサイズ、text-shrinkの最小フォントサイズ。

Examples

Expanding

text-grow: per-line;

拡大ユースケースのA
行の横幅がコンテナの横幅より狭い場合、行のフォントサイズがコンテナの幅に合わせて拡大されます。
フォントサイズは行ごとにばらばらになる可能性があります。
行の横幅がコンテナの横幅より広い場合は、何もしません。

text-grow: per-line 30px;

同上ですが、最大フォントサイズが30pxに制限されます。
そのため横幅いっぱいにならない可能性があります。

text-grow: consistent;

拡大ユースケースのB
行の横幅が最も広い行がコンテナの横幅に合わせて拡大され、他の行も同じ大きさに拡大されます。
コンテナの横幅よりも横幅が広い行がある場合は、何もしません。

Shrinking

text-shrink: per-line;

縮小ユースケースのA
行の横幅がコンテナの横幅より広い場合、行のフォントサイズがコンテナの幅に合わせて縮小されます。
フォントサイズは行ごとにばらばらになる可能性があります。
行の横幅がコンテナの横幅より狭い場合は、何もしません。

text-shrink: per-line 8px;

同上ですが、最小フォントサイズが8pxに制限されます。
そのためコンテナに収まりきらない可能性があります。

text-shrink: consistent;

縮小ユースケースのB
行の横幅が最も広い行がコンテナの横幅に合わせて縮小され、他の行も同じ大きさに縮小されます。
全ての行の横幅がコンテナの横幅より狭い場合は、何もしません。

Combining behaviors

text-grow: per-line;
text-shrink: per-line;

組み合わせユースケースのA
行の横幅がコンテナの横幅より狭い場合、行のフォントサイズがコンテナの幅に合わせて拡大されます。
行の横幅がコンテナの横幅より広い場合、行のフォントサイズがコンテナの幅に合わせて縮小されます。

text-grow: per-line letter-spacing;
text-shrink: per-line letter-spacing;

組み合わせユースケースのB
行の横幅がコンテナの横幅より狭い場合、文字間隔がコンテナの幅に合わせて広がります。
行の横幅がコンテナの横幅より広い場合、文字間隔がコンテナの幅に合わせて狭まります。

text-grow: per-line scale-inline;
text-shrink: per-line scale-inline;

組み合わせユースケースのC
行の横幅がコンテナの横幅より狭い場合、文字が水平方向に拡大されます。
行の横幅がコンテナの横幅より広い場合、文字が水平方向に縮小されます。

text-grow: per-line scale-inline;
text-shrink: per-line scale-inline;

行の横幅が最も広い行がコンテナの横幅に合わせて拡大縮小され、他の行も同じ大きさに拡大縮小されます。
行の横幅がコンテナより広い場合でも狭い場合でも動作します。

text-shrink: per-line scale-inline;
text-align: justify;

組み合わせユースケースのD
コンテナの幅より狭い行は両端揃えになり、コンテナの幅より広い行は水平方向に拡大縮小されます。

Considered alternatives

font-size:fit-widthと、font-sizeプロパティの値として設定する案が検討されました。
コンテナの幅がfont-sizeに依存する場合があるため、技術的に困難と判断されました。

References & acknowledgements

[css-fonts-5] Feature for making text always fit the width of its parent
Roman's presentation at CSSWG meeting

感想

ブラウザやコンテナの幅を広げたら文字もいっしょに大きくなるというアレも、CSSたった1行で簡単に実現できるようになります。
まあ正直文字サイズは勝手に変えてほしくない派なので、あんまり濫用されても困る気がしますが、デザインの専門家であれば何かいいかんじの使い方をしてくれるのではないでしょうか。

31
15
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
31
15

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?