`label` スロット使用時のスライダースタイリングを属性指定と統一

shoelace-style/webawesome

フォームコントロールの label 属性と label スロットで、見た目が異なっていた問題を修正しました。スライダーを含むフォームコントロールで、両方の指定方法が同一のスタイルで表示されるようになります。

背景

#2124 で報告されたとおり、Web Awesomeのスライダーコンポーネントでは、ラベルの指定方法によって見た目が異なるという不整合が存在していました。label 属性で指定した場合と label スロットにコンテンツを置いた場合とで、タイポグラフィのスタイルとスライダートラック上部のスペースが一致していませんでした。

Web Awesomeのフォームコントロール(スライダー、インプット、セレクトなど)は、ラベルを label 属性またはスロットの2通りの方法で設定できます。この柔軟性は意図された設計ですが、スタイリングの統一がなされておらず、利用方法によって視覚的な差異が生じていました。

技術的な変更

変更の核心は slider.styles.ts における CSS セレクタの修正です。スロットにコンテンツが存在するかを判定するセレクタが、クラスベースのアプローチに置き換えられました。

変更前:

/* Add extra space between slider and label, when present */
#label:has(*:not(:empty)) ~ #slider {
  &.horizontal {
    margin-block-start: 0.5em;
  }

変更後:

/* Add extra space between slider and label, when present */
#label.has-label ~ #slider {
  &.horizontal {
    margin-block-start: 0.5em;
  }

変更前のセレクタ :has(*:not(:empty)) はスロットに直接子要素が存在する場合のみを検出します。一方、has-label クラスはコンポーネント側(JavaScript)でラベルの有無を統一的に判定して付与されるため、label 属性とスロットの両方をカバーできます。この修正により、スライダートラック上部の 0.5em のマージンがどちらの指定方法でも一様に適用されるようになります。

設計判断

CSSの:has()擬似クラスによるDOM状態の検出から、JavaScriptが付与するクラスへの依存へと方針が転換されています。

:has(*:not(:empty)) はスロットの実際のDOM構造を直接参照するアプローチです。これはスロットコンテンツのみを対象とし、label 属性で設定されたラベルは考慮しません。対して has-label クラスはコンポーネントのロジックレイヤーで「ラベルが存在するかどうか」を一元的に判断した結果をCSSに伝える設計です。属性とスロットのどちらでラベルが設定されても、同じクラスが付与されます。

このアプローチにより、スタイリングの条件判断をCSSとJavaScriptのどちらで行うかが明確に役割分担されます。ラベルの存在判定はコンポーネントロジックが担い、CSSはその結果を受け取ってスタイルを適用するだけに徹しています。

まとめ

セレクタを1行修正するだけの小さな変更ですが、CSSがDOMの内部構造を直接観察するのではなく、コンポーネントロジックが設定したクラスを参照するという設計の整合性を取り戻しています。label 属性とスロットという2つのAPIを等価に扱うという一貫性が、この修正で担保されました。

記事メタデータ

Generated by:
Claude Sonnet 4.6 for DiffDaily
LLM Trace:
61bcb0d9

この記事は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リンク記法の正確性

ファイル名付きシンタックスハイライトやGitHubのIssue/PRリンク記法が正しく使用されています。

対象読者への適合性 ✓ PASS

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

CSSセレクタやコンポーネント設計に関する解説が含まれており、専門知識を持つエンジニアという対象読者に適した技術レベルで記述されています。

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

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

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

Diff内容との照合 ✓ PASS

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

記事で引用されているコードは、提供されたDiff情報と正確に一致しており、ファイルパスも正しいです。

技術用語の正確性 ✓ PASS

技術用語の正確な使用

`:has()`擬似クラス、スロット、属性といった技術用語が文脈に応じて正確に使用されています。

説明の技術的正確性 ✓ PASS

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

`:has()`セレクタが属性を検出できない理由と、クラスベースのアプローチが両方のケースをカバーできる理由についての説明は、技術的に正確で論理的です。

事実の突合 ✓ PASS

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

記事内のすべての主張は、PRのDescriptionやDiff内のコードで裏付けられており、ハルシネーションは検出されませんでした。「設計判断」セクションも、コードの意図を的確に解説したものであり、事実に基づいています。

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

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

PR番号(#2151)やIssue番号(#2124)などの固有名詞・数値はすべて正確に記載されています。

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

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

記事のタイトルは、PRの主題である「`label`スロットと`label`属性使用時のスタイリングを統一する」という内容を的確に要約しています。

外部知識の正確性 ✓ PASS

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

PR情報に含まれないバージョン情報やリリース予定などの外部知識は含まれておらず、事実に忠実です。

時間表現の正確性 ✓ PASS

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

過去の問題(不整合があった)と今回の修正という時間関係が、過去形などを用いて正しく表現されています。