# Rules

Every rule maps to one or more WCAG 2.1 success criteria. Rules without a WCAG mapping are tagged as best practices.

| Rule ID | WCAG | Level | Description |
| --- | --- | --- | --- |
| `accesslint-001` | 2.4.2 | A | Documents must have a <title> element to provide users with an overview of content. |
| `accesslint-002` | Best practice | A | Page must have a mechanism to bypass repeated blocks of content. |
| `accesslint-003` | Best practice | A | Page should contain a level-one heading. |
| `accesslint-004` | 4.1.2 | A | Frames must have an accessible name. |
| `accesslint-005` | 4.1.2 | A | Frame titles should be unique. |
| `accesslint-006` | 1.4.4 | AA | Viewport meta tag must not disable user scaling. |
| `accesslint-007` | 2.2.1 | A | Meta refresh must not redirect or refresh automatically. |
| `accesslint-008` | 2.2.1 | A | Meta refresh must not be used with a delay (no exceptions). |
| `accesslint-009` | 2.2.2 | A | The <blink> element must not be used. |
| `accesslint-010` | 2.2.2 | A | The <marquee> element must not be used. |
| `accesslint-011` | 1.1.1 | A | Images must have alternate text. Add an alt attribute to <img> elements. Decorative images may use an empty alt attribute (alt=""), role='none', or role='presentation'. |
| `accesslint-012` | 1.1.1 | A | SVG elements with an img, graphics-document, or graphics-symbol role must have an accessible name via a <title> element, aria-label, or aria-labelledby. |
| `accesslint-013` | 1.1.1, 4.1.2 | A | Image inputs (<input type="image">) must have alternate text via alt, aria-label, or aria-labelledby. The text should describe the button action, not the image. |
| `accesslint-014` | Best practice | A | Image alt text should not duplicate adjacent link or button text. When alt text repeats surrounding text, screen reader users hear the same information twice. |
| `accesslint-015` | Best practice | A | Image alt text should not contain words like 'image', 'photo', or 'picture' — screen readers already announce the element type. |
| `accesslint-016` | 1.1.1, 4.1.2 | A | Image map <area> elements must have alternative text. |
| `accesslint-017` | 1.1.1 | A | <object> elements must have alternative text. |
| `accesslint-018` | 1.1.1 | A | Elements with role='img' must have an accessible name. |
| `accesslint-019` | 2.1.1 | A | Server-side image maps must not be used. |
| `accesslint-020` | 4.1.2 | A | Form elements must have labels. Use <label>, aria-label, or aria-labelledby. |
| `accesslint-021` | Best practice | A | Form fields should not have multiple label elements. |
| `accesslint-022` | 4.1.2 | A | Select elements must have a programmatically associated label via <label>, aria-label, or aria-labelledby. |
| `accesslint-023` | 4.1.2 | A | Input buttons must have discernible text via value, aria-label, or aria-labelledby. |
| `accesslint-024` | 1.3.5 | AA | Autocomplete attribute must use valid values from the HTML specification. |
| `accesslint-025` | Best practice | A | Interactive elements with visible text must have accessible names that contain that text. |
| `accesslint-026` | Best practice | A | Form elements should not use title attribute as the only accessible name. |
| `accesslint-027` | Best practice | A | Elements should not have tabindex greater than 0, which disrupts natural tab order. |
| `accesslint-028` | Best practice | A | Elements that receive keyboard focus must have an appropriate role so assistive technologies can convey their purpose. Non-interactive elements with tabindex='0' need a valid interactive ARIA role. |
| `accesslint-029` | 4.1.2 | A | Interactive controls must not be nested inside each other. |
| `accesslint-030` | 2.1.1 | A | Scrollable regions must be keyboard accessible. |
| `accesslint-031` | Best practice | A | Accesskey attribute values must be unique. |
| `accesslint-032` | 2.4.7 | AA | Elements in sequential focus order must have a visible focus indicator. |
| `accesslint-033` | Best practice | A | Heading levels should increase by one; skipping levels (e.g. h2 to h4) makes navigation harder. |
| `accesslint-034` | Best practice | A | Headings must have discernible text. |
| `accesslint-035` | Best practice | A | Paragraphs should not be styled to look like headings. |
| `accesslint-036` | Best practice | A | Page should have exactly one main landmark. |
| `accesslint-037` | Best practice | A | Page should not have more than one banner landmark. |
| `accesslint-038` | Best practice | A | Page should not have more than one contentinfo landmark. |
| `accesslint-039` | Best practice | A | Page should not have more than one main landmark. |
| `accesslint-040` | Best practice | A | Banner landmark should not be nested within another landmark. |
| `accesslint-041` | Best practice | A | Contentinfo landmark should not be nested within another landmark. |
| `accesslint-042` | Best practice | A | Main landmark should not be nested within another landmark. |
| `accesslint-043` | Best practice | A | Aside (complementary) landmark should be top-level or directly inside main. |
| `accesslint-044` | Best practice | A | Landmarks should have unique labels when there are multiple of the same type. |
| `accesslint-045` | Best practice | A | All page content should be contained within landmarks. |
| `accesslint-046` | 1.3.1 | A | <ul> and <ol> must only contain <li>, <script>, or <template> as direct children. |
| `accesslint-047` | 1.3.1 | A | <li> elements must be contained in a <ul>, <ol>, or <menu>. |
| `accesslint-048` | 1.3.1 | A | <dt> and <dd> elements must be contained in a <dl>. |
| `accesslint-049` | 1.3.1 | A | <dl> elements must only contain <dt>, <dd>, <div>, <script>, or <template>. |
| `accesslint-050` | 1.4.12 | AA | Letter spacing set with !important in style attributes must be at least 0.12em. |
| `accesslint-051` | 1.4.12 | AA | Line height set with !important in style attributes must be at least 1.5. |
| `accesslint-052` | 1.4.12 | AA | Word spacing set with !important in style attributes must be at least 0.16em. |
| `accesslint-053` | 1.3.4 | AA | Page orientation must not be restricted using CSS transforms. |
| `accesslint-054` | 4.1.2 | A | ARIA role values must be valid. |
| `accesslint-055` | 4.1.2 | A | ARIA attributes must be valid (correctly spelled). |
| `accesslint-056` | 4.1.2 | A | ARIA attributes must have valid values. |
| `accesslint-057` | 4.1.2 | A | Elements with ARIA roles must have all required ARIA attributes. |
| `accesslint-058` | 4.1.2 | A | ARIA attributes must be allowed for the element's role. |
| `accesslint-059` | 4.1.2 | A | ARIA role must be appropriate for the element. |
| `accesslint-060` | 1.3.1 | A | Certain ARIA roles require specific child roles to be present. |
| `accesslint-061` | 1.3.1 | A | Certain ARIA roles must be contained within specific parent roles. |
| `accesslint-062` | 4.1.2 | A | aria-hidden='true' must not be present on the document body. |
| `accesslint-063` | 4.1.2 | A | Elements with aria-hidden='true' must not contain focusable elements. |
| `accesslint-064` | 4.1.2 | A | ARIA commands must have an accessible name. |
| `accesslint-065` | 4.1.2 | A | ARIA input fields must have an accessible name. |
| `accesslint-066` | 4.1.2 | A | ARIA toggle fields must have an accessible name. |
| `accesslint-067` | 4.1.2 | A | ARIA meter elements must have an accessible name. |
| `accesslint-068` | 4.1.2 | A | ARIA progressbar elements must have an accessible name. |
| `accesslint-069` | 4.1.2 | A | ARIA dialogs must have an accessible name. |
| `accesslint-070` | 4.1.2 | A | ARIA tooltips must have an accessible name. |
| `accesslint-071` | 4.1.2 | A | ARIA treeitem elements must have an accessible name. |
| `accesslint-072` | 4.1.2 | A | ARIA attributes must not be prohibited for the element's role. |
| `accesslint-073` | 4.1.2 | A | Elements with role='presentation' or role='none' must not be focusable or have global ARIA attributes. |
| `accesslint-074` | 4.1.2 | A | Elements with a role that makes children presentational must not contain focusable content. |
| `accesslint-075` | 4.1.2 | A | Buttons must have discernible text. |
| `accesslint-076` | 4.1.2 | A | <summary> elements must have an accessible name. |
| `accesslint-077` | 2.4.4, 4.1.2 | A | Links must have discernible text via content, aria-label, or aria-labelledby. |
| `accesslint-078` | 2.4.1 | A | Skip links must point to a valid target on the page. |
| `accesslint-079` | 1.4.1 | A | Links within text blocks must be distinguishable by more than color alone. |
| `accesslint-080` | 3.1.1 | A | The <html> element must have a lang attribute. |
| `accesslint-081` | 3.1.1 | A | The lang attribute on <html> must have a valid value. |
| `accesslint-082` | 3.1.2 | AA | The lang attribute must have a valid value on all elements. |
| `accesslint-083` | 3.1.1 | A | The lang and xml:lang attributes on <html> must match. |
| `accesslint-084` | 1.3.1 | A | All cells in a table using headers attribute must reference valid header IDs. |
| `accesslint-085` | 1.3.1 | A | Table headers should be associated with data cells. |
| `accesslint-086` | 1.3.1 | A | Data cells in tables larger than 3x3 should have associated headers. |
| `accesslint-087` | 1.3.1 | A | The scope attribute on table headers must have a valid value. |
| `accesslint-088` | Best practice | A | Table header cells should have visible text. |
| `accesslint-089` | 4.1.2 | A | IDs used in ARIA and label associations must be unique to avoid broken references. |
| `accesslint-090` | 1.2.2 | A | Video elements must have captions via <track kind='captions'>. |
| `accesslint-091` | 1.2.1 | A | Audio elements should have a text alternative or transcript. |
| `accesslint-092` | 1.4.3 | AA | Text elements must have sufficient color contrast against the background. |
| `accesslint-093` | 1.4.6 | AAA | Text elements must have enhanced color contrast against the background (WCAG AAA). |
