代表的な面接トピック

フロントエンド面接:フォントメトリクスの垂直方向の配置崩れを text-box-trim で修正するにはどうしますか?

フロントエンド難しい
Offer.cc 編集チーム公開日 更新日

質問

フォントメトリクスの垂直方向の配置崩れを text-box-trim で修正するにはどうしますか?

課題とユースケース

デザインシステム内のボタン、バッジ、見出しは視覚的な中央揃えで配置されることが多いですが、CSSの行ボックス(line box)にはフォント固有の上下のハーフリーディング(half-leading)が残ります。text-box-trimtext-box-edge を使用してテキストボックスを制御する方法、ブラウザサポートが限られている環境への適用方法、フォント読み込み・書字モード・アクセシビリティへの配慮方法を説明してください。

面接官が見ているポイント

  • グリフ、フォントメトリクス、行ボックス、要素のボックスモデルを明確に区別できているか。
  • start、end、および両側のトリミングを正確に説明できるか。
  • text-box-edge を用いて cap、ex、text、alphabetic、leading の各エッジを適切に選択できるか。
  • 論理ブロック方向、フォントフォールバック、プログレッシブエンハンスメントを適切に扱えるか。
  • 実ブラウザ、実フォント、アクセシビリティの検証結果に基づいて結果を評価できるか。

最初に確認すべき質問

  • 目的はオプティカルな中央揃えですか、フォント間の差異吸収ですか、それとも固定の line-height とベースラインの維持ですか?
  • コンポーネントは、対応ブラウザでのみ本機能を有効にする仕様でよいですか?
  • 対象となるフォント、サイズ、言語、書字モード、ズーム倍率の範囲は何ですか?
  • テキストの折り返しは発生しますか?また、フォーカスリングやタップ領域(hit area)は維持する必要がありますか?

30秒での回答

従来の行ボックスにはフォントのハーフリーディングが含まれているため、同じ padding を設定してもフォントによって垂直方向の見た目が異なる場合があります。text-box-trim はブロック軸のエッジをトリミングし、text-box-edge はエッジとして使用するフォントメトリクスを選択します。これらをまとめたショートハンドが text-box です。実装では、既存の寸法をフォールバックとして保持し、フィーチャクエリ内でプログレッシブエンハンスメントとして適用し、ボタンの最小タップ領域を確保した上で、フォント、言語、書字モード、ズーム、支援技術を用いてテストを行います。

詳細な解説ステップ

1. まず4つのボックスを図示・整理する

描画されたグリフ領域、フォントメトリクス、行ボックス、要素の padding および border を切り分けて考えます。テキストボックスのトリミングはブロック軸上のコンテンツ専有領域を変更するものであり、グリフのアウトラインを削ったりタップ領域を縮小させたりするものとして説明してはいけません。

2. ハーフリーディングの発生原因を説明する

line-height がフォント本来の行の高さを超えている場合、余剰スペースは通常、行ボックスの上下(両側)に均等に分配されます。アセンダ、ディセンダ、キャップハイト、xハイトはフォントによって異なるため、同一の line-height を指定してもオプティカルな中心位置がずれる原因になります。

3. トリムするエッジを選択する

text-box-trim には nonetrim-starttrim-endtrim-both を指定できます。ボタンの場合は通常両側のトリミングが必要になりますが、見出しの場合は前の段落との垂直リズムを維持するために block-start エッジのみをトリミングすることがあります。

4. フォントメトリクスを選択する

text-box-edge では、capextextalphabeticleading などのエッジを選択できます。大文字主体の見出しの視覚的基準には cap が適しており、text はフォントのテキスト境界により近くなります。実際のフォントと言語で検証することが不可欠であり、すべてのフォントに万能なメトリクスは存在しません。

5. ショートハンドをローカルに適用する

css
.button {
  text-box: trim-both cap alphabetic;
  padding: 0.625rem 1rem;
}

ショートハンドを使用すると、トリム対象とエッジをまとめて指定できます。グローバルに適用して段落のリズム、アイコン配置、複数行コンテンツを崩さないよう、必要なコンポーネントにスコープを絞って適用します。

6. 論理的な書字方向を考慮する

startend は論理ブロック軸のエッジであり、writing-mode によって変化します。物理的な上下の感覚で捉えるのではなく、異なる direction 値を設定した水平・垂直レイアウトの両方で計測してください。

7. プログレッシブエンハンスメントを設計する

デフォルトでは既存の line-height、padding、最小高さを維持し、@supports (text-box-trim: trim-both) 内で機能を有効化します。ブラウザがこの宣言を無視した場合でも、テキストの可読性が保たれ、ボタンのタッチ・キーボード操作用の寸法が維持される必要があります。

8. フォント読み込みとアクセシビリティを検証する

フォールバックフォント、低速ネットワーク、ズーム、システムフォント、多言語文字列を網羅し、対象フォントが読み込まれた後に計測を行います。フォーカス表示、意図しないクリッピング、スクリーンリーダーの読み上げ順序、実際のタップ判定矩形を確認します。オプティカルな中央揃えのために操作性を犠牲にしてはなりません。

トレードオフと適用限界

この機能により、場当たり的なネガティブマージンやフォントごとの微調整オフセットを排除できますが、ブラウザサポートはまだ限定的であり、フォントメトリクスの差異そのものが消えるわけではありません。また、line-height、padding、Flexbox による配置、適切な最小高さを完全に代替するものではありません。複数行の本文テキスト、動的フォント、複雑なインラインコンテンツへの適用には注意が必要です。デザインの一貫性を担保するため、スクリーンショットだけでなく、対象フォント、採用メトリクス、ブラウザバージョン、許容誤差の記録を残してください。

ロールアウト計画と検証手順

  1. コンポーネントのフォント、サイズ、言語、書字モード、許容誤差を記録する。
  2. 現在のスタイルをベースラインとして保持し、フィーチャクエリの分岐を追加して、インタラクティブ要素の最小サイズを固定する。
  3. Chrome 133 およびプロジェクトで対象とする他のブラウザでテストする(MDN では本プロパティは Baseline ではなく限定的な提供状況として分類されています)。
  4. 実フォントおよびフォールバックフォントを用いて、オプティカルオフセット、フォーカスリング、折り返し、ズーム時の挙動を計測する。
  5. スクリーンショット、計測値、ブラウザバージョン、フォールバック方針をコンポーネントの受入記録(acceptance record)に保存する。

よくあるミスとフォローアップ質問

ミス 1:トリムをグリフのクリッピングと混同する

本機能は主にテキストボックスのエッジを調整するものであり、グリフのアウトラインをピクセル単位で切り取るわけではありません。フォントメトリクス、行ボックス、要素のボックスモデルに立ち返って説明してください。

ミス 2:グローバルに trim-both を設定する

段落、リスト、複数行コンテンツには通常の垂直リズムが必要です。コンポーネント単位のスコープとフォールバックの境界を明確に示してください。

ミス 3:デフォルトフォントのみで確認する

フォントの読み込み失敗、言語の変更、システムフォントの適用によってメトリクスは変化します。フォールバック時や低速ネットワーク下でのテストを含めてください。

ミス 4:論理軸を無視する

trim-start は必ずしも物理的な上側とは限りません。縦書きレイアウトや異なる書字方向値におけるブロック軸の動作を確認してください。

ミス 5:見た目だけを確認し、操作性を確認しない

トリミングによってタッチ領域、キーボードフォーカス、可読領域が損なわれてはなりません。最小サイズ、フォーカスリング、支援技術への影響を確認するテストを提示してください。

公開情報ソース

関連する質問