wa-prose ユーティリティで長文コンテンツに階層的リズムを付与
wa-prose ユーティリティは、ドキュメントやブログ記事、マーケティングコピーといった長文コンテンツに階層的・非対称のタイポグラフィリズムを適用できるようにします。wa-font-size-* と組み合わせるだけで、文字サイズに応じて余白が比例的に変化し、全体の視認性とアクセシビリティが向上します。
背景
以前の #2368 PR では、docs.css 内に #content スコープでのみ有効な「プローズリズム」を実装し、ドキュメントページの可読性を改善しました。しかし同様のリズムは、ブログやマーケティングページなど他の長文領域でも有用であることが判明しました。ページごとに #content ID を付与する手法では再利用性が低く、外部サイトでの埋め込みも困難でした。そこで 公式ユーティリティとして wa-prose を提供 し、任意の要素にクラスを付与するだけで同等のリズムを得られるようにしました。
技術的な変更
テンプレートへのクラス注入 では、packages/webawesome/docs/_includes/base.njk の main 要素に条件付きで wa-prose を付与します。proseContent フラグが真の場合にクラスが追加され、ドキュメント全体で自動的に適用されます。
<main id="content"{% if not hasFlushMain %} class="content-container{% if proseContent %} wa-prose{% endif %}"{% endif %}>
スタイル変数のマッピング では、既存の docs.css が持つ rem ベースのスペーストークンを wa-prose の em ベーストークンへリマップしています。これにより、ドキュメントレイアウトの幅は維持しつつ、wa-prose のリズムを再利用できます。
#content {
--wa-prose-line-length: var(--content-width-s);
--wa-prose-rhythm-2xs: var(--wa-space-2xs);
--wa-prose-rhythm-xs: var(--wa-space-xs);
--wa-prose-rhythm-s: var(--wa-space-s);
--wa-prose-rhythm-m: var(--wa-space-m);
--wa-prose-rhythm-l: var(--wa-space-l);
--wa-prose-rhythm-xl: var(--wa-space-xl);
}
設定データの追加 では、docs/docs.json に "proseContent": true を追加し、デフォルトでドキュメントページ全体に wa-prose を有効化しています。
{
"proseContent": true
}
ユーティリティ定義 は packages/webawesome/src/styles/utilities/prose.css に実装され、:where() ラッパで specificity 0,0,0 を保証しつつ、階層的余白やフォント設定を行います。--wa-prose-rhythm-scale で全体の余白倍率を調整でき、--wa-prose-line-length で読みやすさの列幅を制御します。
@layer wa-utilities {
:where(.wa-prose) {
--wa-prose-rhythm-scale: 1;
--wa-prose-rhythm-2xs: calc(0.25em * var(--wa-space-scale) * var(--wa-prose-rhythm-scale));
--wa-prose-rhythm-xs: calc(0.5em * var(--wa-space-scale) * var(--wa-prose-rhythm-scale));
--wa-prose-rhythm-s: calc(0.75em * var(--wa-space-scale) * var(--wa-prose-rhythm-scale));
--wa-prose-rhythm-m: calc(1em * var(--wa-space-scale) * var(--wa-prose-rhythm-scale));
--wa-prose-rhythm-l: calc(1.5em * var(--wa-space-scale) * var(--wa-prose-rhythm-scale));
--wa-prose-rhythm-xl: calc(2em * var(--wa-space-scale) * var(--wa-prose-rhythm-scale));
--wa-prose-line-length: 65ch;
max-inline-size: var(--wa-prose-line-length);
font-variant-numeric: oldstyle-nums proportional-nums;
hanging-punctuation: first last allow-end;
& :where(h1) { font-size: 2.5625em; }
& :where(h2) { font-size: 2em; }
& :where(h3) { font-size: 1.5625em; }
/* 省略: h4-h6、リスト、コード、テーブル等の余白定義 */
}
}
エクスポートの統合 は packages/webawesome/src/styles/utilities.css で @import url('utilities/prose.css'); を追加し、ビルドプロセスに新ユーティリティを組み込みました。
@import url('utilities/gap.css');
@import url('utilities/text.css');
@import url('utilities/layout.css');
@import url('utilities/prose.css');
@import url('utilities/size.css');
@import url('utilities/variants.css');
ドキュメントの更新 では、docs/utilities/prose.md を新規作成し使用方法・例・カスタマイズ手順を詳細に記載。さらに changelog.md に wa-prose 追加を追記し、変更履歴にも可視化しています。
設計判断
em ベースの余白設計 は、wa-font-size-* と自然に連動させるための核心的選択です。rem ベースの既存スケールと比べ、文字サイズが変わるコンテナでも均一な視覚感覚が保たれます。スケールは単一の --wa-prose-rhythm-scale カスタムプロパティで一括調整でき、サイドバーなどの密度が高い領域で簡易的に縮小できます。
:where() ラッパ による 0,0,0 specificity は、利用者が余計な CSS Specificity を意識せずに上書きできるようにする意図です。これにより、テーマやコンポーネント側のスタイルが wa-prose の規則を簡単に上書きでき、カスタマイズの自由度が高まります。
既存 wa-native スタイルの再利用 は、コード重複を避けつつデザイン一貫性を保つ妥協です。ヘッディングやリスト等は wa-native が提供するベースブロックをそのまま継承し、余白だけを wa-prose が上書きする構造にしました。結果として、他ユーティリティ(wa-cluster、wa-stack など)と組み合わせても期待通りに機能します。
オプトアウト機構 wa-not-prose は、UI コンポーネント内部でリズムだけを除外したいケースに対応しています。revert-layer を利用した実装は、CSS のレイヤー機構を活用し、影響範囲を最小限に抑える設計です。
テンプレートフラグ proseContent による自動有効化は、ドキュメント全体への一括適用を簡素化し、個別ページでの設定ミスを防止します。デフォルトで true に設定されているため、過去の #content スコープのスタイルは削除され、ユーティリティ単位での管理へ移行しました。
まとめ
wa-prose ユーティリティは、em ベースの階層的余白 と ゼロ特異性の CSS を組み合わせ、長文コンテンツの可読性を統一的に向上させます。テンプレート・スタイル・ドキュメント全体の改修により、既存ページへの影響は最小限に抑えつつ、カスタマイズとオプトアウトの柔軟性も提供しました。今後は他のテーマやサードパーティサイトでも同一クラスを付与するだけで、プローズリズムを活用できる基盤が整いました。