Rules
Every rule cora knows, under the engine that runs it. Each rule’s ID links to CORA’s guidance on fixing what it finds, which links the rule’s own documentation, and the tables give each rule’s:
- Level, the WCAG version and level that first require what it checks, or
best practicefor a rule no WCAG success criterion requires. - WCAG success criteria, the ones it checks, if any.
- Category, what it checks, which Categories describes.
- Severity, the severity of the issues it finds.
- Fix class, what fixing the issues it finds takes, which Fix classes describes.
- Description of what it checks.
Each rule of an engine that checks pages, such as axe, is in the default set, which Vispero keeps, or outside it, such as a rule axe-core calls experimental or deprecated. The config’s rules decides which run: its standard, WCAG 2.2 AA by default, runs the rules of the default set at its version and level and below, bestPractices runs the default set’s best practices, and overrides set the rules a rule ID, a WCAG success criterion, a category or an engine names to on, off or report, which shows their findings without ever failing the gate. A WCAG success criterion, a category or an engine reaches only the rules of the default set, so a rule outside it runs only where an override names it by its ID, as axe/p-as-heading here:
import { defineConfig } from '@vispero/cora/config';
export default defineConfig({ rules: { standard: 'WCAG 2.1 AA', overrides: { 'axe/region': 'off', '1.4.6': 'on', forms: 'report', 'axe/p-as-heading': 'on', }, },});Categories
Section titled “Categories”| Category | Its rules check that |
|---|---|
aria |
ARIA roles, states and properties are valid, and used where the specification allows them. |
color |
Text has enough contrast with its background, and color is not the only way information is shown. |
forms |
Form fields have labels, and say what information they collect. |
keyboard |
The page works from a keyboard: focus reaches what it should, and people can skip past repeated content. |
language |
The page, and each part in another language, name their language. |
name-role-value |
Interactive elements have an accessible name, and expose their role and state. |
parsing |
The markup is unambiguous and current: no two elements share an ID, and no obsolete element such as marquee is used. |
semantics |
Headings and landmarks are marked up for what they are, and links and labels say what they do. |
sensory-and-visual-cues |
People can zoom and resize the page, and targets are large enough to hit. |
structure |
Lists and other structure are marked up as the content is organized, and the layout adapts to text spacing and orientation. |
tables |
Data tables mark their headers, and associate each cell with them. |
text-alternatives |
Images and other non-text content have a text alternative, and documents and frames a title. |
time-and-media |
Audio and video have captions, and content that moves, blinks or refreshes can be controlled. |
Fix classes
Section titled “Fix classes”| Fix class | Meaning |
|---|---|
mechanical |
A fix needs no authored text or visual decision. |
content |
A fix needs authored text. |
design |
A fix needs a visual decision. |
manual |
A fix needs a person to work out what to change, beyond authored text or a visual decision. |
In the default set
Section titled “In the default set”These rules run where the config’s standard covers their level, or, for a best practice, where bestPractices is on, unless an override says otherwise. By default says whether each runs with the defaults, WCAG 2.2 AA and the best practices.
| Rule | By default | Level | WCAG | Category | Severity | Fix class | Description |
|---|---|---|---|---|---|---|---|
axe/accesskeys |
on | best practice | none | keyboard | serious | mechanical | accesskey attribute value should be unique |
axe/area-alt |
on | 2.0 A | 2.4.4, 4.1.2 | text-alternatives | critical | content | Active <area> elements must have alternative text |
axe/aria-allowed-attr |
on | 2.0 A | 4.1.2 | aria | critical | mechanical | Elements must only use supported ARIA attributes |
axe/aria-allowed-role |
on | best practice | none | aria | minor | mechanical | ARIA role should be appropriate for the element |
axe/aria-braille-equivalent |
on | 2.0 A | 4.1.2 | aria | serious | content | aria-braille attributes must have a non-braille equivalent |
axe/aria-command-name |
on | 2.0 A | 4.1.2 | aria | serious | content | ARIA commands must have an accessible name |
axe/aria-conditional-attr |
on | 2.0 A | 4.1.2 | aria | serious | mechanical | ARIA attributes must be used as specified for the element’s role |
axe/aria-deprecated-role |
on | 2.0 A | 4.1.2 | aria | minor | mechanical | Deprecated ARIA roles must not be used |
axe/aria-dialog-name |
on | best practice | none | aria | serious | content | ARIA dialog and alertdialog nodes should have an accessible name |
axe/aria-hidden-body |
on | 2.0 A | 1.3.1, 4.1.2 | aria | critical | mechanical | aria-hidden=“true” must not be present on the document body |
axe/aria-hidden-focus |
on | 2.0 A | 4.1.2 | name-role-value | serious | mechanical | ARIA hidden element must not be focusable or contain focusable elements |
axe/aria-input-field-name |
on | 2.0 A | 4.1.2 | aria | serious | content | ARIA input fields must have an accessible name |
axe/aria-meter-name |
on | 2.0 A | 1.1.1 | aria | serious | content | ARIA meter nodes must have an accessible name |
axe/aria-progressbar-name |
on | 2.0 A | 1.1.1 | aria | serious | content | ARIA progressbar nodes must have an accessible name |
axe/aria-prohibited-attr |
on | 2.0 A | 4.1.2 | aria | serious | mechanical | Elements must only use permitted ARIA attributes |
axe/aria-required-attr |
on | 2.0 A | 4.1.2 | aria | critical | mechanical | Required ARIA attributes must be provided |
axe/aria-required-children |
on | 2.0 A | 1.3.1 | aria | critical | mechanical | Certain ARIA roles must contain particular children |
axe/aria-required-parent |
on | 2.0 A | 1.3.1 | aria | critical | mechanical | Certain ARIA roles must be contained by particular parents |
axe/aria-roles |
on | 2.0 A | 4.1.2 | aria | critical | mechanical | ARIA roles used must conform to valid values |
axe/aria-tab-name |
on | 2.0 A | 4.1.2 | aria | serious | content | ARIA tab nodes must have an accessible name |
axe/aria-text |
on | best practice | none | aria | serious | mechanical | “role=text” should have no focusable descendants |
axe/aria-toggle-field-name |
on | 2.0 A | 4.1.2 | aria | serious | content | ARIA toggle fields must have an accessible name |
axe/aria-tooltip-name |
on | 2.0 A | 4.1.2 | aria | serious | content | ARIA tooltip nodes must have an accessible name |
axe/aria-treeitem-name |
on | best practice | none | aria | serious | content | ARIA treeitem nodes should have an accessible name |
axe/aria-valid-attr |
on | 2.0 A | 4.1.2 | aria | critical | mechanical | ARIA attributes must conform to valid names |
axe/aria-valid-attr-value |
on | 2.0 A | 4.1.2 | aria | critical | mechanical | ARIA attributes must conform to valid values |
axe/autocomplete-valid |
on | 2.1 AA | 1.3.5 | forms | serious | mechanical | autocomplete attribute must be used correctly |
axe/avoid-inline-spacing |
on | 2.1 AA | 1.4.12 | structure | serious | mechanical | Inline text spacing must be adjustable with custom stylesheets |
axe/blink |
on | 2.0 A | 2.2.2 | time-and-media | serious | mechanical | <blink> elements are deprecated and must not be used |
axe/button-name |
on | 2.0 A | 4.1.2 | name-role-value | critical | content | Buttons must have discernible text |
axe/bypass |
on | 2.0 A | 2.4.1 | keyboard | serious | manual | Page must have means to bypass repeated blocks |
axe/color-contrast |
on | 2.0 AA | 1.4.3 | color | serious | design | Elements must meet minimum color contrast ratio thresholds |
axe/color-contrast-enhanced |
off | 2.0 AAA | 1.4.6 | color | serious | design | Elements must meet enhanced color contrast ratio thresholds |
axe/definition-list |
on | 2.0 A | 1.3.1 | structure | serious | mechanical | <dl> elements must only directly contain properly-ordered <dt> and <dd> groups, <script>, <template> or <div> elements |
axe/dlitem |
on | 2.0 A | 1.3.1 | structure | serious | mechanical | <dt> and <dd> elements must be contained by a <dl> |
axe/document-title |
on | 2.0 A | 2.4.2 | text-alternatives | serious | content | Documents must have <title> element to aid in navigation |
axe/duplicate-id-aria |
on | 2.0 A | 4.1.2 | parsing | critical | mechanical | IDs used in ARIA and labels must be unique |
axe/empty-heading |
on | best practice | none | name-role-value | minor | content | Headings should not be empty |
axe/empty-table-header |
on | best practice | none | name-role-value | minor | content | Table header text should not be empty |
axe/form-field-multiple-labels |
on | 2.0 A | 3.3.2 | forms | moderate | mechanical | Form field must not have multiple label elements |
axe/frame-focusable-content |
on | 2.0 A | 2.1.1 | keyboard | serious | mechanical | Frames with focusable content must not have tabindex=-1 |
axe/frame-title |
on | 2.0 A | 4.1.2 | text-alternatives | serious | content | Frames must have an accessible name |
axe/frame-title-unique |
on | 2.0 A | 4.1.2 | text-alternatives | serious | content | Frames must have a unique title attribute |
axe/heading-order |
on | best practice | none | semantics | moderate | mechanical | Heading levels should only increase by one |
axe/html-has-lang |
on | 2.0 A | 3.1.1 | language | serious | content | <html> element must have a lang attribute |
axe/html-lang-valid |
on | 2.0 A | 3.1.1 | language | serious | content | <html> element must have a valid value for the lang attribute |
axe/html-xml-lang-mismatch |
on | 2.0 A | 3.1.1 | language | moderate | mechanical | HTML elements with lang and xml:lang must have the same base language |
axe/identical-links-same-purpose |
off | 2.0 AAA | 2.4.9 | semantics | minor | content | Links with the same name must have a similar purpose |
axe/image-alt |
on | 2.0 A | 1.1.1 | text-alternatives | critical | content | Images must have alternative text |
axe/image-redundant-alt |
on | best practice | none | text-alternatives | minor | content | Alternative text of images should not be repeated as text |
axe/input-button-name |
on | 2.0 A | 4.1.2 | name-role-value | critical | content | Input buttons must have discernible text |
axe/input-image-alt |
on | 2.0 A | 1.1.1, 4.1.2 | text-alternatives | critical | content | Image buttons must have alternative text |
axe/label |
on | 2.0 A | 4.1.2 | forms | critical | content | Form elements must have labels |
axe/label-content-name-mismatch |
on | 2.1 A | 2.5.3 | semantics | serious | content | Elements must have their visible text as part of their accessible name |
axe/label-title-only |
on | best practice | none | forms | serious | content | Form elements should have a visible label |
axe/landmark-banner-is-top-level |
on | best practice | none | semantics | moderate | mechanical | Banner landmark should not be contained in another landmark |
axe/landmark-contentinfo-is-top-level |
on | best practice | none | semantics | moderate | mechanical | Contentinfo landmark should not be contained in another landmark |
axe/landmark-main-is-top-level |
on | best practice | none | semantics | moderate | mechanical | Main landmark should not be contained in another landmark |
axe/landmark-no-duplicate-banner |
on | best practice | none | semantics | moderate | mechanical | Document should not have more than one banner landmark |
axe/landmark-no-duplicate-contentinfo |
on | best practice | none | semantics | moderate | mechanical | Document should not have more than one contentinfo landmark |
axe/landmark-no-duplicate-main |
on | best practice | none | semantics | moderate | mechanical | Document should not have more than one main landmark |
axe/landmark-one-main |
on | best practice | none | semantics | moderate | mechanical | Document should have one main landmark |
axe/landmark-unique |
on | best practice | none | semantics | moderate | content | Landmarks should have a unique role or role/label/title (i.e. accessible name) combination |
axe/link-in-text-block |
on | 2.0 A | 1.4.1 | color | serious | design | Links must be distinguishable without relying on color |
axe/link-name |
on | 2.0 A | 2.4.4, 4.1.2 | name-role-value | serious | content | Links must have discernible text |
axe/list |
on | 2.0 A | 1.3.1 | structure | serious | mechanical | <ul> and <ol> must only directly contain <li>, <script> or <template> elements |
axe/listitem |
on | 2.0 A | 1.3.1 | structure | serious | mechanical | <li> elements must be contained in a <ul> or <ol> |
axe/marquee |
on | 2.0 A | 2.2.2 | parsing | serious | mechanical | <marquee> elements are deprecated and must not be used |
axe/meta-refresh |
on | 2.0 A | 2.2.1 | time-and-media | critical | mechanical | Delayed refresh under 20 hours must not be used |
axe/meta-refresh-no-exceptions |
off | 2.0 AAA | 2.2.4, 3.2.5 | time-and-media | minor | mechanical | Delayed refresh must not be used |
axe/meta-viewport |
on | 2.0 AA | 1.4.4 | sensory-and-visual-cues | moderate | mechanical | Zooming and scaling must not be disabled |
axe/meta-viewport-large |
on | best practice | none | sensory-and-visual-cues | minor | mechanical | Users should be able to zoom and scale the text up to 500% |
axe/nested-interactive |
on | 2.0 A | 4.1.2 | keyboard | serious | manual | Interactive controls must not be nested |
axe/no-autoplay-audio |
on | 2.0 A | 1.4.2 | time-and-media | moderate | manual | <video> or <audio> elements must not play automatically |
axe/object-alt |
on | 2.0 A | 1.1.1 | text-alternatives | serious | content | <object> elements must have alternative text |
axe/page-has-heading-one |
on | best practice | none | semantics | moderate | content | Page should contain a level-one heading |
axe/presentation-role-conflict |
on | best practice | none | aria | minor | mechanical | Elements marked as presentational should be consistently ignored |
axe/region |
on | best practice | none | keyboard | moderate | mechanical | All page content should be contained by landmarks |
axe/role-img-alt |
on | 2.0 A | 1.1.1 | text-alternatives | serious | content | [role=“img”] and [role=“image”] elements must have alternative text |
axe/scope-attr-valid |
on | best practice | none | tables | moderate | mechanical | scope attribute should be used correctly |
axe/scrollable-region-focusable |
on | 2.0 A | 2.1.1, 2.1.3 | keyboard | serious | mechanical | Scrollable region must have keyboard access |
axe/select-name |
on | 2.0 A | 4.1.2 | forms | critical | content | Select element must have an accessible name |
axe/server-side-image-map |
on | 2.0 A | 2.1.1 | text-alternatives | minor | manual | Server-side image maps must not be used |
axe/skip-link |
on | best practice | none | keyboard | moderate | mechanical | The skip-link target should exist and be focusable |
axe/summary-name |
on | 2.0 A | 4.1.2 | name-role-value | serious | content | Summary elements must have discernible text |
axe/svg-img-alt |
on | 2.0 A | 1.1.1 | text-alternatives | serious | content | <svg> elements with an img or image role must have alternative text |
axe/tabindex |
on | best practice | none | keyboard | serious | mechanical | Elements should not have tabindex greater than zero |
axe/table-duplicate-name |
on | best practice | none | tables | minor | content | Tables should not have the same summary and caption |
axe/target-size |
on | 2.2 AA | 2.5.8 | sensory-and-visual-cues | serious | design | All touch targets must be 24px large, or leave sufficient space |
axe/td-headers-attr |
on | 2.0 A | 1.3.1 | tables | serious | mechanical | Table cell headers attributes must refer to other <th> elements in the same table |
axe/th-has-data-cells |
on | 2.0 A | 1.3.1 | tables | serious | mechanical | Table headers in a data table must refer to data cells |
axe/valid-lang |
on | 2.0 AA | 3.1.2 | language | serious | content | lang attribute must have a valid value |
axe/video-caption |
on | 2.0 A | 1.2.2 | text-alternatives | critical | manual | <video> elements must have captions |
Outside the default set
Section titled “Outside the default set”These rules run only where an override of the config names them by their IDs, since a criterion, a category or an engine reaches only the rules of the default set: axe-core calls them experimental or deprecated, or, as axe/frame-tested, they report what coverage already records.
| Rule | Level | WCAG | Category | Severity | Fix class | Description |
|---|---|---|---|---|---|---|
axe/aria-roledescription |
2.0 A | 4.1.2 | aria | serious | mechanical | aria-roledescription must be on elements with a semantic role |
axe/audio-caption |
2.0 A | 1.2.1 | time-and-media | critical | manual | <audio> elements must have a captions track |
axe/css-orientation-lock |
2.1 AA | 1.3.4 | structure | serious | design | CSS Media queries must not lock display orientation |
axe/duplicate-id |
2.0 A, obsolete in 2.2 | 4.1.1 | parsing | minor | mechanical | id attribute value must be unique |
axe/duplicate-id-active |
2.0 A, obsolete in 2.2 | 4.1.1 | parsing | serious | mechanical | IDs of active elements must be unique |
axe/focus-order-semantics |
best practice | none | keyboard | minor | mechanical | Elements in the focus order should have an appropriate role |
axe/frame-tested |
best practice | none | structure | critical | manual | Frames should be tested with axe-core |
axe/hidden-content |
best practice | none | structure | minor | manual | Hidden content on the page should be analyzed |
axe/landmark-complementary-is-top-level |
best practice | none | semantics | moderate | mechanical | Aside should not be contained in another landmark |
axe/p-as-heading |
2.0 A | 1.3.1 | semantics | serious | mechanical | Styled <p> elements must not be used as headings |
axe/table-fake-caption |
2.0 A | 1.3.1 | tables | serious | mechanical | Data or header cells must not be used to give caption to a data table. |
axe/td-has-header |
2.0 A | 1.3.1 | tables | critical | mechanical | Non-empty <td> elements in larger <table> must have an associated table header |