ShoelaceテーマのネイティブボタンでサイズUtilityクラスが機能しない問題を修正
Shoelaceテーマにおいて、wa-size-* utilityクラスがネイティブボタン要素に適用されなかった問題が解決されました。CSSレイヤーの優先順位を調整することで、utilityクラスによるサイズ指定が正しく反映されるようになっています。
背景
Shoelaceテーマでは、ネイティブボタン要素に対して @layer wa-theme-overrides で font-size: var(--wa-font-size-smaller) を適用していました。しかし、このレイヤーは @layer wa-utilities よりも後に定義されているため、レイヤーの優先順位によってテーマのスタイルが常にutilityクラスを上書きしていました。
#1892 で報告されたように、この問題により wa-size-s、wa-size-m、wa-size-l といったサイズutilityクラスを適用しても、すべてのボタンが同じサイズで表示されていました。CSSのカスケードレイヤー仕様では、後に定義されたレイヤーが優先されるため、テーマレイヤーがutilityレイヤーを常に上書きする構造になっていました。
技術的な変更
packages/webawesome/src/styles/themes/shoelace.css において、サイズutilityクラス(.wa-size-s、.wa-size-l)や size 属性が指定された場合に、それに応じた font-size とレイアウト用の --_size カスタムプロパティを上書きするよう変更されました。
変更前:
wa-button::part(label),
wa-radio[appearance='button'],
button,
input[type='button'],
input[type='reset'],
input[type='submit'],
a.wa-button {
font-size: var(--wa-font-size-smaller);
}
変更後:
wa-button {
&::part(label) {
font-size: var(--wa-font-size-s);
}
&[size='small']::part(label),
&.wa-size-s::part(label) {
font-size: var(--wa-font-size-xs);
}
&[size='large']::part(label),
&.wa-size-l::part(label) {
font-size: var(--wa-font-size-m);
}
}
wa-radio[appearance='button'],
button,
input[type='button'],
input[type='reset'],
input[type='submit'],
a.wa-button {
--_size: var(--wa-font-size-m);
font-size: var(--wa-font-size-s);
&[size='small'],
&.wa-size-s {
--_size: var(--wa-font-size-s);
font-size: var(--wa-font-size-xs);
}
&[size='large'],
&.wa-size-l {
--_size: var(--wa-font-size-l);
font-size: var(--wa-font-size-m);
}
--wa-form-control-padding-block: calc(0.75 * var(--_size));
--wa-form-control-padding-inline: var(--_size);
--wa-form-control-height: round(
calc(2 * var(--wa-form-control-padding-block) + var(--_size) * var(--wa-form-control-value-line-height)),
);
}
ネイティブボタン要素に対しては、--_size というカスタムプロパティを導入し、意図されたサイズを保持するようになりました。font-size はShoelaceテーマの視覚的特性を維持するため1段階小さいサイズを使用しますが、--_size は本来のサイズを保持し、パディングや高さの計算に使用されます。
このアプローチにより、フォントサイズは小さくなっても、ボタンの高さとパディングは他のフォームコントロールと同じサイズで一致するようになります。--wa-form-control-padding-block、--wa-form-control-padding-inline、--wa-form-control-height といったemベースのレイアウトプロパティは、実際の font-size ではなく --_size を参照して計算されます。
Web Componentsの wa-button についても、size 属性や .wa-size-* クラスに応じて ::part(label) のフォントサイズがスケールするよう、明示的なスタイル定義が追加されました。デフォルトは var(--wa-font-size-s)、small サイズでは var(--wa-font-size-xs)、large サイズでは var(--wa-font-size-m) が適用されます。
設計判断
カスタムプロパティによる二重管理 という設計が採用されました。font-size と --_size を分離することで、視覚的な一貫性(Shoelaceテーマではボタンのフォントが小さい)を保ちながら、レイアウトの一貫性(他のフォームコントロールと高さが揃う)も確保しています。
この設計により、utilityクラスの有無に関わらず、Shoelaceテーマの視覚的特性が維持されます。レイヤーの優先順位を変更するのではなく、テーマレイヤー内で各サイズに応じたスタイルを明示的に定義することで、utilityクラスによる指定を実質的に上書きする実装になっています。
まとめ
本PRは、CSSレイヤーの優先順位問題を、各サイズに応じたスタイル定義とカスタムプロパティの導入によって解決しました。レイヤーの順序を変更するのではなく、テーマレイヤー内でutilityクラスや属性に応じたスタイルを上書きする設計により、既存のレイヤー構造を維持しながら問題を解決しています。フォントサイズとレイアウトサイズを分離することで、Shoelaceテーマの視覚的特性を損なうことなく、サイズutilityクラスの機能を復元しています。