`<wa-badge>`のアイコン有無による高さ不一致をCSSで修正
アイコンをスロットに挿入した際に <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のパーツセレクタを精確に絞り込むことで、テキストや他のスロットへの影響を回避しながら一貫したバッジ高さを実現しています。