wa-prose ユーティリティで長文コンテンツに階層的リズムを付与

shoelace-style/webawesome

wa-prose ユーティリティは、ドキュメントやブログ記事、マーケティングコピーといった長文コンテンツに階層的・非対称のタイポグラフィリズムを適用できるようにします。wa-font-size-* と組み合わせるだけで、文字サイズに応じて余白が比例的に変化し、全体の視認性とアクセシビリティが向上します。

背景

以前の #2368 PR では、docs.css 内に #content スコープでのみ有効な「プローズリズム」を実装し、ドキュメントページの可読性を改善しました。しかし同様のリズムは、ブログやマーケティングページなど他の長文領域でも有用であることが判明しました。ページごとに #content ID を付与する手法では再利用性が低く、外部サイトでの埋め込みも困難でした。そこで 公式ユーティリティとして wa-prose を提供 し、任意の要素にクラスを付与するだけで同等のリズムを得られるようにしました。

技術的な変更

テンプレートへのクラス注入 では、packages/webawesome/docs/_includes/base.njkmain 要素に条件付きで wa-prose を付与します。proseContent フラグが真の場合にクラスが追加され、ドキュメント全体で自動的に適用されます。

<main id="content"{% if not hasFlushMain %} class="content-container{% if proseContent %} wa-prose{% endif %}"{% endif %}>

スタイル変数のマッピング では、既存の docs.css が持つ rem ベースのスペーストークンを wa-proseem ベーストークンへリマップしています。これにより、ドキュメントレイアウトの幅は維持しつつ、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.mdwa-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-clusterwa-stack など)と組み合わせても期待通りに機能します。

オプトアウト機構 wa-not-prose は、UI コンポーネント内部でリズムだけを除外したいケースに対応しています。revert-layer を利用した実装は、CSS のレイヤー機構を活用し、影響範囲を最小限に抑える設計です。

テンプレートフラグ proseContent による自動有効化は、ドキュメント全体への一括適用を簡素化し、個別ページでの設定ミスを防止します。デフォルトで true に設定されているため、過去の #content スコープのスタイルは削除され、ユーティリティ単位での管理へ移行しました。

まとめ

wa-prose ユーティリティは、em ベースの階層的余白ゼロ特異性の CSS を組み合わせ、長文コンテンツの可読性を統一的に向上させます。テンプレート・スタイル・ドキュメント全体の改修により、既存ページへの影響は最小限に抑えつつ、カスタマイズとオプトアウトの柔軟性も提供しました。今後は他のテーマやサードパーティサイトでも同一クラスを付与するだけで、プローズリズムを活用できる基盤が整いました。

記事メタデータ

Generated by:
gpt-oss-120b for DiffDaily
LLM Trace:
2887010a

この記事はAIによって自動生成されています。内容の正確性については、必ずソースコードやPRを確認してください。

品質レビュー結果

Review Status:
承認済み
Review Count:
1回
Reviewed by:
gpt-oss-120b for DiffDaily

Review Criteria:

記事構成 ✓ PASS

Title, Context, Technical Detailの存在と明確さ

リード文がタイトル直下に配置され、背景・技術的変更・設計判断・まとめの各セクションが揃っており、総論→各論→結論の構成が明確です。

カスタムMarkdown構文 ⚠ WARNING

シンタックスハイライト・GitHubリンク記法の正確性

コードブロックは `言語:ファイルパス` 形式で正しく記述されていますが、PRリンクが `[PR #2370](URL)` となっており、仕様の `[ #2370 ](URL)` 形式と異なります。

対象読者への適合性 ✓ PASS

エンジニア向けの適切な技術レベルと表現

専門エンジニア向けの記述で、初心者向けの余計な解説はなく適切です。

パラグラフ・ライティング ⚠ WARNING

トピックセンテンス・1段落1トピック・段落長

各セクションは総論と各論で構成されていますが、技術的変更セクションに明確な結論パラグラフが欠けており、総論→各論→結論の完全な流れがやや不完全です。段落のトピックセンテンスは概ね正しく設定されています。

Diff内容との照合 ✓ PASS

コードブロックとDiff内容の一致

記事内のコードブロックは提供されたDiffと一致しており、ファイル名・変更内容ともに正確です。

技術用語の正確性 ✓ PASS

技術用語の正確な使用

使用されている技術用語はPR説明と一致し、誤用や不適切な用語は見られません。

説明の技術的正確性 ✓ PASS

技術的主張の正確性と論理性

技術的説明はDiffとPRの記述に裏付けられており、根拠のない主張はありません。

事実の突合 ✓ PASS

PR情報による主張の裏付け(ハルシネーション検出)

全ての事実はPR情報とDiffに基づいており、外部知識の捏造や時間表現の歪曲はありません。

数値・固有名詞の確認 ✓ PASS

PR番号・コミットID・バージョン等の正確性

PR番号やファイル名・プロパティ名など数値・固有名詞は正確です。

タイトル・説明との一致 ✓ PASS

記事タイトル・説明とPR内容の一致

記事タイトルはPRの内容(wa-prose ユーティリティの追加)を的確に表現しています。

外部知識の正確性 ✓ PASS

PRに記載のない外部知識(LTS、サポート状況など)の不使用

記事ではPRに記載されていないバージョン情報やリリーススケジュール等の外部知識は使用していません。

時間表現の正確性 ✓ PASS

時間表現がPR情報と一致しているか

時間表現は記載されておらず、PRの記述と矛盾する箇所もありません。