`<wa-badge>`のアイコン有無による高さ不一致をCSSで修正

shoelace-style/webawesome

アイコンをスロットに挿入した際に <wa-badge> コンポーネントの高さが微妙にずれる問題が、line-height: 0 の1行追加で解決されました。

背景

インライン要素のデフォルト line-height が、アイコン有無で <wa-badge> の高さに差異を生じさせていました。Issue #2280 で報告されたこのバグは、start / end スロットにアイコンを配置した場合と配置しない場合でバッジの高さが変わるという、UIの一貫性を損なうものでした。

HTMLのインライン要素は vertical-align のデフォルト値として baseline を持ちます。アイコンのような置換要素がスロットに挿入されると、その vertical-align 計算によってライン全体の高さが押し上げられ、アイコンがない場合と比べてバッジ全体の高さが変化していました。

この問題はCSSの基本的なレンダリング仕様に起因するため、バッジのサイズ変更やパディング調整では根本的な解決にならず、スロット部分のラインボックス計算そのものを無効化するアプローチが必要でした。

技術的な変更

badge.styles.ts に対して、[part='start'][part='end']line-height: 0 を適用する4行のCSSルールが追加されました。

変更前:

  slot[name='start']::slotted(*) {
    margin-inline-end: 0.375em;
  }

変更後:

  /* Prevents vertical space when icons with vertical-align are slotted in - https://github.com/shoelace-style/webawesome/issues/2280 */
  [part='start'],
  [part='end'] {
    line-height: 0;
  }

  slot[name='start']::slotted(*) {
    margin-inline-end: 0.375em;
  }

line-height: 0 をスロットのラッパー要素([part='start'] / [part='end'])に設定することで、そのコンテナ内のラインボックスの高さがゼロに折りたたまれます。スロット内のアイコン自体はフレックスレイアウトや絶対サイズによって表示されるため、視覚的な表示には影響せず、ラインボックスによる余分な垂直スペースのみが除去されます。

設計判断

[part='start'][part='end'] というShadow DOMのパーツ属性を対象に line-height: 0 を適用する方式が採用されました。

このアプローチでは、変更の影響範囲をアイコンが挿入されるスロット部分に限定しています。また、::slotted(*) ではなく親コンテナ側に適用している点も特徴的で、スロットに挿入されたアイコン要素のスタイルを直接変更せずにレイアウト上の問題を解決しています。

まとめ

line-height: 0 というCSSの基本的な性質を活用し、変更をわずか4行に抑えつつ根本原因を解消した修正です。Shadow DOMのパーツセレクタを精確に絞り込むことで、テキストや他のスロットへの影響を回避しながら一貫したバッジ高さを実現しています。

記事メタデータ

Generated by:
Claude Sonnet 4.6 for DiffDaily
LLM Trace:
8f7d86b0

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

品質レビュー結果

Review Status:
リトライ後承認
Review Count:
2回 (改善を経て承認)
Reviewed by:
Gemini 2.5 Pro for DiffDaily

Review Criteria:

記事構成 ✓ PASS

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

「リード文→背景→技術的な変更→設計判断→まとめ」という理想的な「総論→各論→結論」の構成が明確に守られています。各セクションの役割が明確で、非常に理解しやすいです。

カスタムMarkdown構文 ✓ PASS

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

ファイル名付きシンタックスハイライト(```typescript:path/to/file```)およびGitHubのIssue/PRへのリンク記法がガイドラインに準拠しており、正しく使用されています。

対象読者への適合性 ✓ PASS

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

CSSの`line-height`や`vertical-align`、Shadow DOMの`part`属性といった専門用語を前提としており、対象読者であるエンジニアに適した技術レベルで記述されています。

パラグラフ・ライティング ✓ PASS

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

各セクションが総論→各論の構成になっており、各パラグラフはトピックセンテンスで始まるなど、パラグラフ・ライティングの原則が遵守されています。可読性が非常に高いです。

Diff内容との照合 ✓ PASS

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

記事内のコードブロックは、提供されたDiff情報を正確に反映しています。ファイルパス、追加されたコード、コメントのいずれも完全に一致しています。

技術用語の正確性 ✓ PASS

技術用語の正確な使用

「ラインボックス」「置換要素」「Shadow DOM Part」など、CSSとWeb Componentsに関する技術用語が文脈に沿って正確に使用されています。

説明の技術的正確性 ✓ PASS

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

`line-height: 0`がなぜこの問題を解決するのかという技術的な解説が、CSSのレンダリング仕様に基づいており、論理的かつ正確です。

事実の突合 ✓ PASS

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

記事内のすべての主張(問題の背景、原因、解決策)は、PRのタイトル、Description、Diff内のコードやコメントによって裏付けられています。ハルシネーションは検出されませんでした。

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

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

PR番号(#2377)とIssue番号(#2280)が正確に記載されています。

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

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

記事のタイトル「`<wa-badge>`のアイコン有無による高さ不一致をCSSで修正」は、PRの主題を的確に要約しています。

外部知識の正確性 ✓ PASS

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

PR情報に記載のないバージョンサポート情報やリリース日程などの外部知識の捏造は見られませんでした。技術解説はコードを説明する範囲に留まっています。

時間表現の正確性 ✓ PASS

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

「〜でした」「〜されました」といった過去形の表現が使われており、完了した変更を報告するPRの文脈と一致しています。時間表現の歪曲はありません。