label-has-associated-control
Configuration
Rule Details
Enforce that a <label> tag has a text label AND an associated form control.
There are two supported ways to associate a label with a control:
- Nesting — wrap the control in the label.
htmlFor— give the label anhtmlForattribute pointing at the control's DOM id.
This rule checks that any <label> tag (or a configured custom label
component) either (1) wraps a form control or (2) declares an htmlFor
attribute, AND that the label has accessible text content.
Examples of incorrect code for this rule:
Examples of correct code for this rule:
Rule Options
This rule takes one optional object argument:
labelComponents(default[]) — custom React component names treated as a<label>. Glob patterns are supported via minimatch (e.g.*LabelmatchesMUILabel,????LabelmatchesLinkLabelbut notCustomLabel).labelAttributes(default[]) — extra attribute names that count as accessible text on the label (or any descendant withindepth), in addition toalt/aria-label/aria-labelledby. Useful when a custom component renders its label from a string prop.controlComponents(default[]) — custom React component names that count as a nested form control. These are added to the built-in list:input,meter,output,progress,select,textarea. Glob patterns are supported (e.g.Custom*matchesCustomInput).assert(default"either") — which association strategy to require. One of"htmlFor","nesting","both","either":"htmlFor"— the label must have a validhtmlForattribute."nesting"— the label must wrap a form control."both"— the label must satisfy both conditions."either"— the label must satisfy at least one condition.
depth(default2, max25) — how deep within a<label>(or label component) the rule will recurse to find accessible text or a nested form control. Capped at 25 to prevent pathological traversal.
Examples of correct code for this rule with
{ "labelComponents": ["CustomLabel"] }:
Examples of correct code for this rule with
{ "labelAttributes": ["label"] }:
Examples of correct code for this rule with
{ "controlComponents": ["CustomInput"] }:
Examples of incorrect code for this rule with { "assert": "both" }:
Examples of correct code for this rule with { "assert": "both" }:
Examples of correct code for this rule with { "depth": 3 }:
Settings
The rule reads two settings['jsx-a11y'] keys:
attributes.for— list of attribute names recognized as equivalent tohtmlFor. Defaults to["htmlFor"]. When set, the user list replaces the default — include"htmlFor"explicitly to keep it active.components— a{ ComponentName: "html-element" }map. With{ "CustomLabel": "label" },<CustomLabel>is treated as<label>for the listener gate.
These mirror the upstream eslint-plugin-jsx-a11y settings exactly.
Accessibility guidelines
- WCAG 1.3.1 — Info and Relationships
- WCAG 3.3.2 — Labels or Instructions
- WCAG 4.1.2 — Name, Role, Value
Resources
- MDN —
<label> - MDN —
aria-label - MDN —
aria-labelledby - WAI-ARIA 1.2 — Accessible Name and Description Computation