| 1 | # jsx-a11y/control-has-associated-label
|
|---|
| 2 |
|
|---|
| 3 | 🚫 This rule is _disabled_ in the following configs: ☑️ `recommended`, 🔒 `strict`.
|
|---|
| 4 |
|
|---|
| 5 | <!-- end auto-generated rule header -->
|
|---|
| 6 |
|
|---|
| 7 | Enforce that a control (an interactive element) has a text label.
|
|---|
| 8 |
|
|---|
| 9 | There are two supported ways to supply a control with a text label:
|
|---|
| 10 |
|
|---|
| 11 | - Provide text content inside the element.
|
|---|
| 12 | - Use the `aria-label` attribute on the element, with a text value.
|
|---|
| 13 | - Use the `aria-labelledby` attribute on the element, and point the IDREF value to an element with an accessible label.
|
|---|
| 14 | - Alternatively, with an `img` tag, you may use the `alt` attribute to supply a text description of the image.
|
|---|
| 15 |
|
|---|
| 16 | The rule is permissive in the sense that it will assume that expressions will eventually provide a label. So an element like this will pass.
|
|---|
| 17 |
|
|---|
| 18 | ```jsx
|
|---|
| 19 | <button type="button">{maybeSomethingThatContainsALabel}</button>
|
|---|
| 20 | ```
|
|---|
| 21 |
|
|---|
| 22 | ## How do I resolve this error?
|
|---|
| 23 |
|
|---|
| 24 | ### Case: I have a simple button that requires a label.
|
|---|
| 25 |
|
|---|
| 26 | Provide text content in the `button` element.
|
|---|
| 27 |
|
|---|
| 28 | ```jsx
|
|---|
| 29 | <button type="button">Save</button>
|
|---|
| 30 | ```
|
|---|
| 31 |
|
|---|
| 32 | ### Case: I have an icon button and I don't want visible text.
|
|---|
| 33 |
|
|---|
| 34 | Use the `aria-label` attribute and provide the text label as the value.
|
|---|
| 35 |
|
|---|
| 36 | ```jsx
|
|---|
| 37 | <button type="button" aria-label="Save" class="icon-save" />
|
|---|
| 38 | ```
|
|---|
| 39 |
|
|---|
| 40 | ### Case: The label for my element is already located on the page and I don't want to repeat the text in my source code.
|
|---|
| 41 |
|
|---|
| 42 | Use the `aria-labelledby` attribute and point the IDREF value to an element with an accessible label.
|
|---|
| 43 |
|
|---|
| 44 | ```jsx
|
|---|
| 45 | <div id="js_1">Comment</div>
|
|---|
| 46 | <textarea aria-labelledby="js_1"></textarea>
|
|---|
| 47 | ```
|
|---|
| 48 |
|
|---|
| 49 | ### Case: My label and input components are custom components, but I still want to require that they have an accessible text label.
|
|---|
| 50 |
|
|---|
| 51 | You can configure the rule to be aware of your custom components. Refer to the Rule Details below.
|
|---|
| 52 |
|
|---|
| 53 | ```jsx
|
|---|
| 54 | <CustomInput label="Surname" type="text" value={value} />
|
|---|
| 55 | ```
|
|---|
| 56 |
|
|---|
| 57 | ## Rule options
|
|---|
| 58 |
|
|---|
| 59 | This rule takes one optional object argument of type object:
|
|---|
| 60 |
|
|---|
| 61 | ```json
|
|---|
| 62 | {
|
|---|
| 63 | "rules": {
|
|---|
| 64 | "jsx-a11y/control-has-associated-label": [ 2, {
|
|---|
| 65 | "labelAttributes": ["label"],
|
|---|
| 66 | "controlComponents": ["CustomComponent"],
|
|---|
| 67 | "ignoreElements": [
|
|---|
| 68 | "audio",
|
|---|
| 69 | "canvas",
|
|---|
| 70 | "embed",
|
|---|
| 71 | "input",
|
|---|
| 72 | "textarea",
|
|---|
| 73 | "tr",
|
|---|
| 74 | "video",
|
|---|
| 75 | ],
|
|---|
| 76 | "ignoreRoles": [
|
|---|
| 77 | "grid",
|
|---|
| 78 | "listbox",
|
|---|
| 79 | "menu",
|
|---|
| 80 | "menubar",
|
|---|
| 81 | "radiogroup",
|
|---|
| 82 | "row",
|
|---|
| 83 | "tablist",
|
|---|
| 84 | "toolbar",
|
|---|
| 85 | "tree",
|
|---|
| 86 | "treegrid",
|
|---|
| 87 | ],
|
|---|
| 88 | "depth": 3,
|
|---|
| 89 | }],
|
|---|
| 90 | }
|
|---|
| 91 | }
|
|---|
| 92 | ```
|
|---|
| 93 |
|
|---|
| 94 | - `labelAttributes` is a list of attributes to check on the control component and its children for a label. Use this if you have a custom component that uses a string passed on a prop to render an HTML `label`, for example.
|
|---|
| 95 | - `controlComponents` is a list of custom React Components names that will render down to an interactive element.
|
|---|
| 96 | - `ignoreElements` is an array of elements that should not be considered control (interactive) elements and therefore they do not require a text label.
|
|---|
| 97 | - `ignoreRoles` is an array of ARIA roles that should not be considered control (interactive) roles and therefore they do not require a text label.
|
|---|
| 98 | - `depth` (default 2, max 25) is an integer that determines how deep within a `JSXElement` the rule should look for text content or an element with a label to determine if the interactive element will have an accessible label.
|
|---|
| 99 |
|
|---|
| 100 | ### Succeed
|
|---|
| 101 | ```jsx
|
|---|
| 102 | <button type="button" aria-label="Save" class="icon-save" />
|
|---|
| 103 | ```
|
|---|
| 104 |
|
|---|
| 105 | ### Fail
|
|---|
| 106 | ```jsx
|
|---|
| 107 | <button type="button" class="icon-save" />
|
|---|
| 108 | ```
|
|---|
| 109 |
|
|---|
| 110 | ## Accessibility guidelines
|
|---|
| 111 | - [WCAG 1.3.1](https://www.w3.org/WAI/WCAG21/Understanding/info-and-relationships)
|
|---|
| 112 | - [WCAG 3.3.2](https://www.w3.org/WAI/WCAG21/Understanding/labels-or-instructions)
|
|---|
| 113 | - [WCAG 4.1.2](https://www.w3.org/WAI/WCAG21/Understanding/name-role-value)
|
|---|