アイコンボタンにキャレットを付与した際の幅崩れを修正

shoelace-style/webawesome

<wa-button> のアイコンボタンに with-caret 属性を付与すると、Firefoxでキャレットがボタン外にはみ出す表示崩れが発生していました。CSSセレクタの変更と aspect-ratio の上書きにより、この問題が解消されました。

背景

アイコンボタンはその性質上、幅と高さを1:1の正方形に保つ必要があります。そのため button.styles.ts では .button.is-icon-buttonaspect-ratio: 1 が設定されており、アイコン単体での表示は正しく機能していました。しかし、with-caret 属性を追加すると、ボタン内のコンテンツ(アイコン+キャレット)が1:1の制約に収まらず、Firefoxではキャレットが正方形の枠からはみ出す問題が発生していました。

この問題はFirefoxのみで視覚的に顕在化していたとPRに記載されています。

技術的な変更

button.styles.ts.button.is-icon-button:has(wa-icon) セレクタが .button.is-icon-button.caret に変更され、合わせて aspect-ratiomin-width の指定が追加されました。

変更前:

.button.is-icon-button:has(wa-icon) {
  width: auto;
}

変更後:

/* Icon buttons with a caret need to grow to fit both the icon and the caret */
.button.is-icon-button.caret {
  width: auto;
  aspect-ratio: auto;
  min-width: var(--wa-form-control-height);
}

変更のポイントは3つです。まず、セレクタを :has(wa-icon) から .caret クラスへ変更し、キャレットが存在する場合のみこのルールが適用されるようにしています。次に、aspect-ratio: auto で親の aspect-ratio: 1 を上書きし、正方形の制約を解除しています。最後に、min-width: var(--wa-form-control-height) を追加することで、キャレットが付いてもボタンの幅がゼロや極端に小さくなることを防ぎ、アイコン単体分の最低幅を保証しています。

これにより、キャレットなしのアイコンボタン(.button.is-icon-button)には従来の aspect-ratio: 1 が引き続き適用され、キャレットありのボタンのみ幅が内容に合わせて伸長します。

設計判断

セレクタの対象をキャレット有りのケースに限定するアプローチが採用されました。

変更前の :has(wa-icon) セレクタは「wa-icon を含む場合に width: auto にする」という意図でしたが、このルールの適用対象はキャレットの有無に関わらずアイコンを持つすべてのボタンに及んでいました。一方、aspect-ratio を崩す必要があるのはキャレットが存在する場合だけです。.caret クラスへの変更は、意図の変化(「アイコンを持つ」から「キャレットを持つ」)をセレクタに正確に反映させており、副作用の範囲を必要最小限に絞っています。

min-width にフォームコントロール高さのCSS変数 --wa-form-control-height を使用することで、ボタンサイズのバリアントに応じて最低幅も追従する設計になっています。

まとめ

CSSの aspect-ratio:has() の組み合わせが想定外の表示崩れを引き起こすケースへの対処として、適用対象を正確なセレクタで絞り込みつつ aspect-ratio: auto で制約を解除するパターンが示されています。変更行数は最小限ながら、セレクタの意図とCSS変数の活用により保守性を維持した修正といえます。

記事メタデータ

Generated by:
Claude Sonnet 4.6 for DiffDaily
LLM Trace:
f2d0fbd4

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

品質レビュー結果

Review Status:
承認済み
Review Count:
1回
Reviewed by:
Gemini 2.5 Pro for DiffDaily

Review Criteria:

記事構成 ✓ PASS

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

「総論→各論→結論」の構成が明確です。リード文で要旨を、背景・技術詳細・設計判断の各セクションで詳細を、まとめで意義を述べる理想的な構造になっています。

カスタムMarkdown構文 ✓ PASS

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

ファイル名付きシンタックスハイライト(```css:path```)とPR番号のリンク記法([PR #2295](URL))が正しく使用されています。

対象読者への適合性 ✓ PASS

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

CSSセレクタ、`aspect-ratio`、CSS変数といった専門用語を前提としており、専門知識を持つエンジニアという対象読者に適合しています。

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

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

各セクションが総論から始まる構成になっており、各段落もトピックセンテンスで始まるため非常に読みやすいです。1段落1トピックの原則も守られています。

Diff内容との照合 ✓ PASS

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

記事内のコードブロックは、提供されたDiff情報を正確に反映しています。変更前後のコード引用は適切です。

技術用語の正確性 ✓ PASS

技術用語の正確な使用

`aspect-ratio`、`:has()`、CSS変数など、使用されている技術用語はすべて文脈に即して正確です。

説明の技術的正確性 ✓ PASS

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

セレクタの変更理由(適用範囲の限定)や `aspect-ratio: auto` による制約解除など、コード変更に対する技術的な説明は正確かつ論理的です。

事実の突合 ✓ PASS

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

記事内のすべての主張(Firefoxでのみ発生した問題、`aspect-ratio: 1` の存在など)は、PRのDescriptionやDiff内のコードで裏付けられており、ハルシネーションは検出されませんでした。

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

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

PR番号 `#2295` が正確に記載されています。

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

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

記事のタイトルはPRのタイトル「fix icon button width when caret is applied」の内容を正確に和訳・要約しており、主題が一致しています。

外部知識の正確性 ✓ PASS

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

PR情報に含まれない外部知識(バージョン情報、リリース予定など)の記載はなく、提供された情報源に忠実です。

時間表現の正確性 ✓ PASS

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

修正済みの事象を「〜していました」のように過去形で表現しており、時間表現は正確です。