a11y/label-has-control · `<label>` に関連付けられたコントロールがない
label をフィールドと関連付けるには for 属性かラップされたコントロールが必要です。
重大度: warning · カテゴリ: a11y
チェック内容
関連付けられたコントロールを持たない <label> を検出します。コンポーネントのソースを解析します。
次のいずれかが存在すれば関連付けありとみなし、検出しません。
for属性。リテラルまたは式(値は静的にはわからなくても、属性が存在すること自体で十分とみなします)。- ラップされたラベル付け可能な子孫:
input(リテラルなtypeがhiddenの場合を除く)、select、textarea、button、meter、output、progress。
関連付けが見つからない場合でも、内容が静的に判断できない 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'
}
};