Checklist - Code
A and AA levels (Required)
🧩 Markup rules
- Decorative or redundant images have an empty
alt
attribute (1.1.1) - Non-decorative images have a text alternative in the
alt
attribute (1.1.1) - SVG images have
role="img"
andalt
attributes (1.1.1) - Long descriptions of images are provided in the
aria-describedby
attribute (1.1.1) - Markup uses semantic HTML elements (avoid
div
andspan
) (1.3.1) - The page uses one
h1
element and correct heading levels (1.3.1) - Markup order follows the visual order of the content (1.3.2)
- Form fields use the
autocomplete
andinputmode
attributes (1.3.5) - Native HTML elements are preferred over custom elements (2.1.1)
- Custom interactive elements have a
tabindex="0"
attribute (2.1.1) - Elements that should not be focusable are hidden from the tab order (2.1.1)
- The page has a descriptive title in the
title
element (2.4.2) - The page
h1
element content is similar to thetitle
element (2.4.2) - Visible labels are preferred over visually hidden labels (2.5.3)
- Otherwise, visually hidden labels start with the visible labels (2.5.3)
- The
html
element has alang
ISO attribute that matches the main language of the content (3.1.1) - Parts of content in a different language are identified with a
lang
ISO attribute (3.1.2) - Error messages are associated with the form field using the
aria-describedby
attribute (3.3.1) - Form fields with an error have an
aria-invalid="true"
attribute (3.3.1) - Error message have a
role="alert"
attribute (3.3.1) - Form fields are associated to
label
elements using thefor
attribute (3.3.2) - Custom form fields are associated to
label
elements using thearia-labelledby
attribute (3.3.2) - Placeholders are not used as labels (3.3.2)
- Required form fields have a
required
attribute (3.3.2) - Custom required form fields have an
aria-required="true"
attribute (3.3.2) - Required form fields (or optional ones) are clearly identified (3.3.2)
- Hint texts are associated to form fields using the
aria-describedby
attribute (3.3.2) - Groups of form fields are made with the
fieldset
element orrole="group"
(3.3.2) - Error messages are descriptive and explain how to fix the error (3.3.3)
- Custom interactive elements have a
role
attribute (4.1.2) - Custom interactive elements have an accessible name (4.1.2)
- Custom interactive elements clearly indicate their state and value with ARIA (4.1.2)
- Status messages are used sparingly and only when necessary (4.1.3)
- Status messages use the correct ARIA role (
status
,alert
,log
...) (4.1.3)
Styling rules
- The page adapts to both portrait and landscape mode (1.3.4)
- Relative units (em, rem) are used for font sizes, margins and paddings (1.4.4)
- Layouts are flexible and text can be resized to 200% (1.4.4)
- Elements do not have a fixed width bigger than 320px (1.4.10)
- CSS media queries are used to adapt the layout to breakpoints (1.4.10)
- The user can hover a tooltip (1.4.13)
- Content does not flash more than 3 times in a second (2.3.1)
- Skip links are visible when focused (2.4.1)
- Content is not re-ordered with CSS if it changes tab order (2.4.3)
- Links have a meaningful label (at least in context) (2.4.4)
- Focus on interactive elements is visible and consistent (2.4.7)
- Focused elements are at least partially visible, not totally masked by any other element (2.4.11)
🧬 Functionality
- Depending on the content team, live audio content can have AI generated captions (1.2.4)
- The orientation of the page is not restricted (1.3.4)
- Audio does not autoplay, or the user can turn it off (1.4.2)
- Tooltips do not disappear automatically (1.4.13)
- Components do not only rely on mouse events (2.1.1)
- Correct keyboard navigation is implemented for custom interactive elements (2.1.1)
- The user focus is not trapped in an interactive element (2.1.2)
- Do not use single character shortcuts, or provide a way to disable or remap them (2.1.4)
- Shortcuts are active only when the element using them has focus (2.1.4)
- The user can adjust the time limit of interactive content (2.2.1)
- The user can pause, stop or hide content that moves or auto-updates (2.2.2)
- Elements use
keyup
ormouseup
events instead ofkeydown
ormousedown
(2.5.2) - The user can cancel those events mid-way by dragging or with
Esc
(2.5.2) - The user motion preference is respected (no forced motion) (2.5.4)
- Focusing an element does not cause unexpected change (3.2.1)
- Filling a form field does not cause unexpected change (3.2.2)
- Form fields that have not been interacted with do not have errors (3.3.1)
- The user can review and confirm data before submitting important forms (3.3.4)
- The user can access a previously entered value in form fields (3.3.7)
- Authentication forms do not prevent from pasting content (3.3.8)
- Authentication mechanisms (Face ID, Passkeys, OAuth...) are implemented (3.3.8)
- There are alternatives for CAPTCHAs (3.3.8)
AAA level (Optional)
🧩 Markup rules
- Every component has a role and an accessible name (1.3.6)
- If a link label is too generic, visually hidden context is linked to it (2.4.9)
- Abbreviations expanded in a tooltip use the
abbr
element (3.1.4) - Authentication forms fields use the
autocomplete
andinputmode
attributes (3.3.8)
Styling rules
- Font sizes, margins and paddings use relative units (em, rem) (1.4.8)
- Text width is no more than 80 characters per line (40 if CJK) (1.4.8)
- Text is not justified (1.4.8)
- Line height is at least 1.5 in paragraphs (1.4.8)
- Space between paragraphs is at least 2.25 (1.4.8)
- Content does not flash more than 3 times in a second (2.3.2)
- Content respects the user's preferences for reduced motion (2.3.3)
- Focused elements are fully visible, not masked by any other element (2.4.12)
- The website focus indicator is at least 2px wide (2.4.13)
- Contrast ratio for the website focus indicator is at least 3:1 (2.4.13)
🧬 Functionality
- The entire page can be operated with keyboard alone (2.1.3)
- The website does not use time limits, except for live events and non interactive media (2.2.3)
- The user can turn off or delay interruptions (2.2.4)
- User data is saved automatically, and restored after a session interruption (2.2.5)
- User data is preserved for more than 20 hours after inactivity (2.2.6)
- The user is never restricted to a mode of interaction (mouse, keyboard, touch...) (2.5.6)
- The page content does not change automatically (feed refresh, next step...) (3.2.5)
- Help in non-trivial forms or complex steps is implemented (3.3.5)
- Every data submission can be reviewed and confirmed, or cancelled by the user (3.3.6)
- Authentication forms do not prevent from pasting content (3.3.8)