`<wa-details>` のコンテンツオーバーフローをShadow DOM起因のbox-sizingで修正
<wa-details> および ネイティブ <details> 要素の内部に配置した全幅要素が右側にはみ出すバグが修正されました。Shadow DOMのスロット機構が box-sizing の継承を遮断するという根本原因を特定し、!important の復活ではなく対象を絞った border-box の付与で解決しています。
背景
このバグは #2100 がトリガーとなりました。#2100 は、ホスト要素とその子要素への box-sizing 設定から !important を除去したPRです。その変更以降、#2137 として報告されたように、<wa-details> 内に置いた <wa-button> や <wa-input> が右側にはみ出す現象が発生するようになりました。
問題の根本は <details> 要素のShadow DOM にあります。<details> はブラウザ内部でShadow DOMを使用してサマリーとコンテンツをスロットに割り当てますが、このスロットはCSSのデフォルト値である box-sizing: content-box を採用します。Web Awesomeはグローバルスタイルで box-sizing: inherit を設定しているため、スロット内のネイティブ要素はShadow DOMの境界を越えて content-box を継承してしまいます。WAコンポーネントは :host ルールで回避できますが、ネイティブ要素はその恩恵を受けられない点が問題でした。
!important を再導入する案も検討されましたが、それではWAコンポーネント側は修正される一方でネイティブ要素の問題が残ります。この非対称な状況が、より局所的なアプローチを採用する動機となっています。
技術的な変更
修正は2つのファイルへの最小限の追加で構成されています。どちらも box-sizing: border-box を特定のセレクタに直接付与する方針です。
<wa-details> コンポーネントのスタイル修正:
// 変更前
.content {
display: block;
padding-block-start: var(--spacing);
...
}
// 変更後
.content {
display: block;
box-sizing: border-box; /* Ensure contents don't overflow */
padding-block-start: var(--spacing);
...
}
ネイティブ <details> 要素のスタイル修正:
/* 追加 */
&::details-content {
box-sizing: border-box; /* Ensure contents don't overflow */
}
<wa-details> 側では Shadow DOM内の .content クラスに直接 border-box を指定し、ネイティブ <details> 側では ::details-content 擬似要素を用いてブラウザのShadow DOM内スロットに border-box を適用しています。::details-content はブラウザが <details> のコンテンツ領域を公開する擬似要素であり、Shadow DOMの外からそのスタイルを上書きできます。
設計判断
グローバルルールの変更ではなく、影響箇所へのピンポイント適用 が選ばれました。
選択肢として挙げられた !important の再導入は、WAコンポーネントの問題は解消しますがネイティブ要素には効果がなく、問題を半解決するにとどまります。一方、.content と ::details-content を直接ターゲットにする手法は、Shadow DOMのスタイル継承の境界を意識した外科的な修正です。グローバルな box-sizing ポリシーには一切手を加えないため、他のコンポーネントへの波及リスクがありません。
また、::details-content 擬似要素の利用は、ブラウザが仕様として公開したAPIを通じてShadow DOMの内部に干渉するアプローチであり、ブラウザ間の互換性を考慮した選択といえます。
まとめ
Shadow DOMによるCSSプロパティ継承の遮断という構造的な問題に対し、グローバルポリシーを変えずに .content と ::details-content へ border-box を直接付与することで解決しています。Shadow DOMの境界を意識したスタイル設計の難しさと、擬似要素を使った対処の有効性を示す修正です。