コンテンツにスキップ
svelte-vitals
日本語
Esc
移動開く⌘Jプレビュー
このページの内容

a11y/label-has-control · `<label>` に関連付けられたコントロールがない

label をフィールドと関連付けるには for 属性かラップされたコントロールが必要です。

重大度: warning · カテゴリ: a11y

チェック内容

関連付けられたコントロールを持たない <label> を検出します。コンポーネントのソースを解析します。

次のいずれかが存在すれば関連付けありとみなし、検出しません。

  • for 属性。リテラルまたは式(値は静的にはわからなくても、属性が存在すること自体で十分とみなします)。
  • ラップされたラベル付け可能な子孫: input(リテラルな typehidden の場合を除く)、selecttextareabuttonmeteroutputprogress

関連付けが見つからない場合でも、内容が静的に判断できない label は検出しません。対象は {式} の子、コンポーネントの子、{@render …}{@html …}<slot><svelte:fragment>(内容は親から渡される)、ハイフンを含むカスタム要素(form-associated であれば labelable になりうる)です。<label> へのスプレッド属性も同じ理由でスキップします。それ自体が for を供給しうるためです。このルールは「関連付けがないと証明できる」ものだけを検出し、動的な内容を推測することはありません。

<label>Name</label>

なぜ重要か

関連付けられたコントロールを持たない <label> は、支援技術からはフォームラベルではなくただのテキストとして扱われます。スクリーンリーダーは label とそれが指すフィールドの関係を読み上げられません。晴眼ユーザーも label が見た目で約束しているクリックでのフォーカス移動を失いますが、この問題は見た目のレビューでは気づきにくいものです。

修正方法

for にコントロールの id を指定するか、コントロールを <label> でラップします。

<label for="name">Name</label>
<input id="name" />

<label>Name <input /></label>

モードによる違い

ありません。このルールが読むのは同じ .svelte / .ts のソースファイルなので、CLI、Vite プラグインのビルド、ライブダッシュボードの静的ベースラインのいずれでも結果は同一で、レンダリング済み HTML の解析で再評価されることもありません。--route で実行範囲を絞ると、このルールは動きません。コンポーネントスコープのルールには、検出を紐づけるルートが無いためです。

無効化

このルールからは見えない別の方法(コントロール側の aria-labelledby など)で関連付けている場合は、<!-- svelte-vitals-disable-next-line a11y/label-has-control --> で個別の要素を抑制するか、ルールを無効化してください。

export default {
  rules: {
    'a11y/label-has-control': 'off'
  }
};