CSSクランプを使用した最新の流体タイポグラフィ
公開: 2022-03-10 Web開発における流動的なタイポグラフィの概念は何年も前から存在しており、開発者はブラウザで機能させるためにさまざまな回避策に頼らざるを得ませんでした。 新しいCSS clamp
機能により、流動的なタイポグラフィの作成がこれまでになく簡単になりました。
通常、レスポンシブタイポグラフィを実装すると、特定のブレークポイントで値が変化します。 それらは明示的に定義されています。 そのため、設計者は2、3、またはそれ以上の画面サイズの活版印刷値(フォントサイズ、行の高さ、文字間隔など)を提供することが多く、開発者は通常、特定のブレークポイントを対象とするメディアクエリを追加することでこれらの要件を実装します。
タイポグラフィ要素はデザインと同じように見えるかもしれませんが、ブレークポイントに近いビューポート幅の一部の要素には当てはまらない場合があります。 すでに知っているように、ユーザーが利用できるデバイスや画面サイズは、デザインで扱われているもの以外にもたくさんあります。 間にブレークポイントを追加し、スタイルのオーバーライドを追加すると問題が解決する場合がありますが、コードが複雑になり、エッジケースが増え、コードの明確性と保守性が低下するリスクがあります。
流体タイポグラフィは、ビューポートの幅に応じて最小値と最大値の間でスムーズにスケーリングされます。 通常は最小値から始まり、増加し始める特定の画面幅ポイントまで一定値を維持します。 別の画面幅で最大値に達すると、それ以降はその最大値を維持します。 この記事では、流体タイポグラフィも逆の順序で流れる可能性があることを確認します。最大値で開始し、最小値で終了します。
このアプローチにより、特定のブレークポイントやその他のエッジケースの微調整が削減または排除されます。 これは主にタイポグラフィで使用されますが、この流動的なサイジングアプローチは、マージン、パディング、ギャップなどにも機能します。
次の例では、タイトルテキストがスムーズに拡大縮小され、どのビューポート幅でも見栄えがよいことに注目してください。 また、コンテンツがレスポンシブタイポグラフィを保持し、値がブレークポイントでのみ変化することに注意してください。
流体タイポグラフィは前述の問題に対処しますが、すべてのシナリオに理想的であるとは限りません。流体タイポグラフィをレスポンシブタイポグラフィの代わりとして扱うべきではありません。 それぞれに独自のベストプラクティスと適切なユースケースのセットがあり、これらについてはこの記事の後半で説明します。
この記事では、流動的なタイポグラフィについて深く掘り下げ、開発者が過去に使用したさまざまなアプローチを確認します。 また、CSS clamp
関数と、それが流体タイポグラフィの実装を簡素化する方法についても説明し、 clamp
関数のパラメーターを微調整して、流体の動作の開始点と終了点を制御する方法を学習します。 また、アクセシビリティの懸念についても取り上げますが、そのほとんどは今日対処できます。また、現時点では修正できない重要なアクセシビリティの問題の1つについても説明します。
流体タイポグラフィの最初の試み
開発者として、主要なブラウザで開発およびサポートされるまで、不足しているCSS機能を補足するためにJavaScriptを使用することがよくあります。 レスポンシブWebデザインの初期には、FlowType.JSなどのJavaScriptライブラリを使用して流動的なタイポグラフィを実現していました。
流体タイポグラフィの最初の実際のCSS実装には、CSS calc
およびビューポートユニット( vw
およびvh
)が導入されました。
/* Fixed minimum value below the minimum breakpoint */ .fluid { font-size: 32px; } /* Fluid value from 568px to 768px viewport width */ @media screen and (min-width: 568px) { .fluid { font-size: calc(32px + 16 * ((100vw - 568px) / (768 - 568)); } } /* Fixed maximum value above the maximum breakpoint */ @media screen and (min-width: 768px) { .fluid { font-size: 48px; } }
このスニペットは少し複雑に見え、計算には多くの数値が関係しています。 それでは、これをセグメントに分割して、何が起こっているのかについての概要を説明しましょう。 セレクターとメディアクエリに焦点を当てて、それらがカバーするケースを見てみましょう。
.fluid { /* Min value */ } @media screen and (min-width: [breakpoint-min]) { .fluid { /* Preferred value between the minimum and maximum bound */ } @media screen and (min-width: [breakpoint-max]) { /* Max value */ }
モバイルファーストのアプローチでは、最初のセレクターが値を最小範囲に固定します。 最初のメディアクエリは、2つのブレークポイント間の流動的な動作を処理します。 最後のブレークポイントは、値を最大範囲に固定します。 各セレクターとメディアクエリの機能がわかったので、最小境界と最大境界がどのように適用され、流体値がどのように計算されるかを見てみましょう。
.fluid { font-size: [value-min]; } @media (min-width: [breakpoint-min]) { .fluid { font-size: calc([value-min] + ([value-max] - [value-min]) * ((100vw - [breakpoint-min]) / ([breakpoint-max] - [breakpoint-min]))); } } @media (min-width: [breakpoint-max]) { .fluid { font-size: [value-max] } }
これは、最小境界と最大境界の間の値を修正し、2つのブレークポイント間に流動的な動作を追加するという非常に単純なタスクを実現するための多くの定型コードです。
必要なボイラープレートの量にもかかわらず、このアプローチは一般的に流体サイジングを処理するために非常に人気があり、より合理化されたアプローチが必要であることが明らかになりました。 これがCSSクランプ機能の出番です。
CSS clamp
機能
CSS clamp
関数は、最小境界、優先値、最大境界の3つの値を取り、それらの境界の間で現在の値をクランプします。 優先値は、境界間の値を決定するために使用されます。 推奨値には通常、流体効果を実現するためのビューポート単位、パーセンテージ、またはその他の相対単位が含まれます。 これは非常に堅牢で柔軟な関数であるため、固定値に加えて、数学関数や式、およびattr
関数からの値も受け入れることができます。
clamp([value-min], [value-preferred], [value-max]);
この関数は、長さ、頻度、時間、角度、パーセンテージ、数値などの有効な値タイプを受け入れる任意の属性に適用できるため、タイポグラフィやサイズ設定以外にも使用できます。
この記事の執筆時点では、 clamp
機能のブラウザサポートは90%を超えているため、すでに十分にサポートされています。 Internet Explorerなどのサポートされていないデスクトップブラウザの場合、サポートされていないブラウザはclamp
関数を解析できない場合、 font-size
式全体を無視するため、フォールバック値を指定するだけで十分です。
font-size: [value-fallback]; /* Fallback value */ font-size: clamp([value-min], [value-preferred], [value-max]);
CSS clamp
を使用した流体タイポグラフィ
CSS clamp
関数を使用して、次の値を入力してみましょう。
- 最小値—最小フォントサイズと同じです。
- 最大値—最大フォントサイズと同じです。
- 推奨値—流体タイポグラフィのスケーリング方法を決定します—流体の動作と変化速度の開始点と終了点。 この値はビューポートのサイズに依存するため、ビューポートの幅の単位
vw
を使用します。
次の例を見て、フォントサイズを32px
から48px
の間の値に設定しましょう。 次のfont-size
には、最小で32px
、最大で48ピクセルが設定されてい48px
。 現在の値は、ビューポート幅の単位、より正確には、その値が最小境界と最大境界の間にある場合は現在のビューポート幅の4%
によって決定されます。
font-size: clamp(32px, 4vw, 48px);
ビューポートの幅に応じて、この例にどの値が適用されるかを簡単に見てみましょう。これにより、CSSクランプ機能がどのように機能するかをよく理解できます。
ビューポートの幅(px) | 推奨値(px) | 適用値(px) |
---|---|---|
500 | 20 | 32(最小境界に固定) |
900 | 36 | 36(境界間の推奨値) |
1400 | 56 | 48(最大境界に固定) |
このクランプ関数の値には、次の2つの問題があります。
- minとmaxのピクセル値にはアクセスできません。
最小境界と最大境界はピクセル値で表されるため、ユーザーが好みのフォントサイズを変更しても拡大縮小されません。 - 優先値のビューポート値にアクセスできません。
前の場合と同じです。 この値はビューポートの幅にのみ依存し、ユーザー設定は考慮されません。 - 推奨値は不明です。
最初はマジックナンバーのように見える4vw
を使用しています。 さまざまな流動的なフォントサイズの変更を同期できるように、流動的な動作がいつ開始および終了するかを知る必要があります。
px
値を16(デフォルトのブラウザフォントサイズ)で割ることにより、最小および最大境界のpx
値をrem
値に変換することで、最初の問題に簡単に対処できます。 そうすることで、最小値と最大値がユーザーのブラウザ設定に適応します。
font-size: clamp(2rem, 4vw, 3rem);
この値はビューポートのサイズに対応する必要があるため、優先値を使用して別のアプローチを取る必要があります。 ただし、相対的なrem
値を数式に変換することで、簡単に組み合わせることができます。
font-size: clamp(2rem, 4vw + 1rem, 3rem);
これはすべてのアクセシビリティの問題に対する絶対確実な解決策ではないことに注意してください。したがって、流動的なタイポグラフィを十分に拡大できるかどうか、およびユーザーのアクセシビリティ設定に十分に応答するかどうかをテストすることは依然として重要です。 これらの問題については後で説明します。
ただし、必要な流体の動作を実現するために、例( 4vw + 1rem
)からどのように優先値を取得したかはまだわかりません。そこで、優先値を微調整して、その背後にある数学を完全に理解する方法を見てみましょう。 。
流体サイジング機能
推奨値は、流体タイポグラフィ関数の動作に影響します。 より正確には、最小値が変化し始めるビューポート幅ポイントと、最大値に達するビューポート幅ポイントを変更できます。
たとえば、流体の動作をビューポート幅の1200px
で開始し、800pxで終了させたい800px
があります。 さまざまな流体タイポグラフィの同期を維持するために、最小境界と最大境界が異なると、異なる優先値(ビューポート値と相対サイズ)が必要になることに注意してください。
たとえば、通常、ビューポート幅の800px
1200px
間に別の流体動作が発生することは1000px
あり750px
ん。 これにより、次の例のようにサイズの不整合が発生する可能性があります。
この問題を回避するには、優先値がどのように計算されるかを理解し、適切なビューポートと相対値をクランプ関数の優先値に割り当てる必要があります。
それを計算するために使用される関数を理解しましょう。
font-size: clamp([min]rem, [v]vw + [r]rem, [max]rem);
$$ y = \ frac {v} {100} * x + r $$
- x —現在のビューポート幅の値(
px
)。 - y —現在のビューポート幅の値x (
px
)の結果の流動的なフォントサイズ。 - v —流体値の変化率(
vw
)に影響を与えるビューポート幅の値。 - r —ブラウザのフォントサイズと等しい相対サイズ。 デフォルト値は
16px
です。
この関数を使用すると、流体の動作の開始点と終了点を簡単に計算できます。 この例では、 2rem
( 32px
)の最小値は400px
のビューポート幅まで一定です。
$$ 32 = \ frac {4} {100} * x + 16 $$
$$ 16 = \ frac {1} {25} * x $$
$$ x = 400 $$
最大値に同じ関数を適用すると、 800px
のビューポート幅で最大値の3rem
( 48px
)に達することがわかります。
この例の目的は、優先値が流体のタイポグラフィ動作にどのように影響するかを示すことだけでした。 同じ関数をもう少し現実的なシナリオに使用して、より実際的な実例を解いてみましょう。 必要なフォントサイズと流動的な動作を発生させたい特定のポイントに基づいて、アクセシブルな流動的なタイポグラフィを作成します。
特定の開始点と終了点に基づいて優先値パラメーターを計算する
実際のシナリオでよく出てくる実際的な例を見てみましょう。 設計者は、開発者として、次のパラメーターを使用して流動的なタイポグラフィを実装するために必要なフォントサイズとブレークポイントを提供してくれました。
- 最小フォントサイズは
36px
(y1)です - 最大フォントサイズは
52px
(y2)です - 最小値は
600px
のビューポート幅(x1)で終了する必要があります - 最大値は
1400px
ビューポート幅(x2)から開始する必要があります
これらの値を取得して、前に説明した流体サイジング関数に追加してみましょう。
$$ y = \ frac {v} {100} \ cdot x + r $$
最終的に、計算する必要のある2つのパラメーター(ビューポート幅の値v
と相対サイズr
を持つ2つの方程式ができあがります。
$$(1)\; \; \; y_1 = \ frac {v} {100} \ cdot x_1 + r $$
$$(2)\; \; \; y_2 = \ frac {v} {100} \ cdot x_2 + r $$
最初の方程式を取り、それを次の式に変換して使用できます。
$$(1)\; \; \; r = y_1-\ frac {v} {100} \ cdot x_1 $$
2番目の方程式のr
をこの式に置き換えて、 v
を計算する関数を取得できます。
$$ v = \ frac {100 \ cdot(y_2-y_1)} {x_2 --x_1} $$
$$ v = \ frac {100 \ cdot(52-36)} {1400-600} $$
$$ v = 2 $$
ビューポートの幅の値2vw
を取得します。 同様の方法で、 r
を分離し、使用可能なパラメーターを使用して計算できます。
$$ r = \ frac {x_1y_2 --x_2y_1} {x_1 --x_2} $$
$$ r = \ frac {600 \ cdot 52-1400 \ cdot 36} {600-1400} $$
$$ r = 24 $$
注:この値はピクセル単位であり、相対値はrem
で表す必要があるため、ピクセル値を16
で除算し、最終的に1.5rem
になります。
また、36pxの最小境界と36px
の最大境界をrem
に52px
し、すべての値をCSS clamp
関数に追加する必要があります。
font-size: clamp(2.25rem, 2vw + 1.5rem, 3.25rem);
この関数をプロットして、計算値が正しいことを確認できます。
要約すると、次の2つの関数を使用して、フォントサイズとビューポート幅のポイントから優先値パラメーターv
( vw
で表される)とr
( rem
で表される)を計算できます。
$$ v = \ frac {100 \ cdot(y_2-y_1)} {x_2 --x_1} $$
$$ r = \ frac {x_1y_2 --x_2y_1} {x_1 --x_2} $$
clamp
機能がどのように機能し、優先値がどのように計算されるかを完全に理解したので、プロジェクトで一貫性のあるアクセス可能な流体タイポグラフィを簡単に作成し、前述の落とし穴を回避できます。
流体のサイジングに負のビューポート値を使用する
ビューポート値に負の値を使用することで、ビューポートサイズが小さくなるにつれてサイズを拡大することもできます。 ビューポート値が負の場合、デフォルトの流体の動作が逆になります。 また、前の例の前述の2つの方程式を解くことにより、流体の動作が特定のポイントで開始および終了するように、相対的なサイズを調整する必要があります。
font-size: clamp(3rem, -4vw + 6rem, 4.5rem);
私は自分のプロジェクトでこの逆の構成を使用していませんが、プロジェクトまたは設計でこの要件に遭遇した場合は、興味深いと思うかもしれません。
流体タイポグラフィ視覚化ツール
プロジェクトに取り組んでいる間、複数の異なる流体タイポグラフィ構成を作成する必要がありました。 私はブラウザーで構成をテストしていて、開発者が流動的なタイポグラフィの動作を視覚化して微調整するのに役立つツールを作成するというアイデアを思いつきました。 Josh W.Comeauの「CSSforJS開発者」コースのデモの1つに触発され、Modern FluidTypographyToolを作成しました。
開発者はこのツールを使用して、流動的なタイポグラフィコードスニペットを作成および微調整し、流動的な動作を視覚化して、複数のインスタンスの同期を維持できます。 このツールは構成へのリンクを生成することもできるため、開発者はリンクをコードコメントまたはドキュメントに含めることができるため、他のユーザーは流動的なサイズ設定の動作を簡単に確認できます。
このプロジェクトは無料でオープンソースなので、バグを報告して貢献してください。 あなたの考えや機能のリクエストを聞いてうれしいです!
アクセシビリティの懸念
rem
値を使用しても、すべてのユーザーが流動的なタイポグラフィに自動的にアクセスできるようになるわけではなく、フォントサイズがユーザーのフォント設定に応答することしかできないことを繰り返すことが重要です。 CSS clamp
機能をビューポートユニットと組み合わせて使用して流体のサイジングを実現すると、考慮する必要のある別の一連の欠点が発生します。
Adrian Roselliは、これらの問題を彼のブログ投稿で広範囲にわたってテストおよび文書化しています。
「vw
単位を使用するか、clamp()
を使用してテキストのサイズを制限すると、ユーザーがテキストを元のサイズの200%に拡大縮小できない可能性があります。 その場合は、1.4.4 Resize text(AA)でのWCAGの失敗ですので、必ずズームで結果をテストしてください。」
—エイドリアンロゼリ
JavaScriptを使用してズームイベントが発生したことを検出し、通常のrem
値で流体のサイズをオーバーライドするクラスを適用することで、最初からこの問題に取り組みたいと思いました。
/* Apply fluid typography for default zoom level (not zoomed) */ .title { font-size: clamp(2rem, 4vw + 1rem, 3rem); } /* Revert to responsive typography if zoom is active */ body.zoom-active .title { font-size: 2rem; } @media screen and (min-width: 768px) { body.zoom-active .title { font-size: 3rem; } }
サイズ変更などの他の通常のビューポートイベントを検出できるように、JavaScriptを使用してズームイベントを確実に検出できないことに気付いたので、驚かれるかもしれません。
この記事の執筆時点では、92%のブラウザを確実にサポートするVisual Viewport API仕様がありますが、スケール(ズームレベル)値は機能しません。ズーム(スケール)値に関係なく同じ値を返します。 利用可能なドキュメント、実例、またはユースケースがないことは言うまでもありません。 このAPIがそのような堅実なブラウザサポートを持っていることを考えると、これは少し奇妙です。 いくつかの回避策は存在しますが、完全に信頼できるわけではなく、イベントが発生した後でのみ、ページが最初に読み込まれたときにページが拡大されたかどうかを検出できません。
Visual Viewport APIが意図したとおりに機能した場合、ズームイベントでCSSクラスを簡単に切り替えることができます。
/* This code won't work because visualViewport.scale is buggy * and always returns the same value. This might be fixed in the future. */ function checkZoomLevel() { if (window.visualViewport.scale === 1) { document.body.classList.remove("zoom-active"); } else { document.body.classList.add("zoom-active"); } } window.addEventListener("resize", checkZoomLevel);
残念ながら、流動的なサイズ設定を適用することにより、ブラウジング中にズーム機能を使用する一部のユーザーがコンテンツにアクセスできなくなるリスクがあります。 流体タイポグラフィの信頼性が高く、よりアクセスしやすいフォールバックを作成できるようになるまで、流体サイズを慎重に使用し、ズームレベルがWebコンテンツアクセシビリティガイドライン(WCAG)に準拠しているかどうかをテストしてください。
推奨されるユースケース
流動的なタイポグラフィは、最小サイズと最大サイズの差が大きい、大きくて目立つテキスト要素に最適です。 大きなタイトルは、それに応じて拡大縮小されない場合、小さなビューポートではより不快で場違いに見えます。
一貫したサイジングを維持する必要がある場合は、流体サイジングもお勧めします。
Elise Heinは、流体タイポグラフィのベストプラクティスに関する彼女の記事で同様の結論に達しました。
「ビューポート相対タイポグラフィが読みやすさの点でブレークポイントベースのサイジングよりも優れている多くの特定の領域を見つけようとしましたが、失敗しました。 表示テキストの設定と一貫した測定の維持の2つがあります。」
—エリーゼハイン
本文の通常の場合のように、最小値と最大値の差がほんの数ピクセルである場合、流体タイポグラフィはそれほど効果的または有用ではありません。 最小フォントサイズと最大フォントサイズの差が小さい本文テキストは、フォントサイズが大きい場合のように、どのビューポート幅でも見違えることはありません。 このような場合は、ブレークポイントを使用した通常のレスポンシブタイポグラフィを使用することをお勧めします。
結論
流体タイポグラフィは、レスポンシブタイポグラフィの代わりとして機能するのではなく、特定のユースケースの拡張機能として機能する必要があります。 最小サイズと最大サイズの差が大きいテキストをスムーズに拡大縮小し、一貫したサイズを維持するには、流動的なタイポグラフィを使用する必要があります。
CSS clamp
機能で複数の流体タイポグラフィ要素を使用する場合、流体スケーリングが同期していることを確認する必要があります。 これを行うには、ビューポートの幅と相対値を計算し、CSS clamp
関数でそれらを優先値として使用します。 また、流動的なタイポグラフィがユーザーのフォントサイズの設定に適応するように、rem単位などの相対単位を使用することにも留意する必要があります。
また、流体タイポグラフィがユーザーのズーム機能を制限し、アクセシビリティの問題を引き起こす可能性があることも確認しました。 コンテンツが十分にズームできないことがテストで明らかになった場合は、ズームを使用して流体タイポグラフィをテストし、通常のレスポンシブタイポグラフィに戻すことが重要です。
ズームアクションが発生したときに流体のタイポグラフィ値をオーバーライドすることで、この問題に対処できるはずです。 ただし、現在、Visual Viewport APIが正しく機能しておらず、ユーザーのズームイベントに応答しないため、これを行うことはできません。
参考文献
clamp()
、MDN- 「とにかく、なぜタイプは流動的でなければならないのですか?」エリーゼハイン
- 「簡略化された流体タイポグラフィ」、Chris Coyier
- 「レスポンシブタイプとズーム」、Adrian Roselli
- 「
vh
およびvw
ユニットを使用した応答性の高い流動的なタイポグラフィ」MichaelRiethmuller