Designer Compliance Pathway
Visual and interaction design decisions that determine whether your product is usable, and whether it meets the EAA. Half of accessibility is decided before a single line of code is written.
Last reviewed: 2026-04-07
Colour, contrast, and visual hierarchy
If a user can't read it, nothing else you've designed matters. Contrast is the bit everything else sits on top of.
What the law says
Three WCAG criteria do the heavy lifting here. 1.4.3 (Contrast Minimum) sets the floor at 4.5:1 for normal text and 3:1 for large text (18pt, or 14pt bold). 1.4.11 (Non-text Contrast) pushes that 3:1 minimum out to UI components and informative graphics — form field borders, icons, focus rings, all of it. And 1.4.1 (Use of Colour) says you can never let colour be the only way you communicate something. A red error border with no icon, no text, no other signal? That's a direct fail. EN 301 549 9.1.4.1, 9.1.4.3 and 9.1.4.11 carry the same rules forward for any web content under the EAA.
What it means in practice
Pick the palette with contrast in mind from day one. The expensive mistake is letting marketing finalise the brand palette, baking it into the design system, and only running it past accessibility at the end. By that point, changing anything costs months of work and political capital you probably don't have. What actually works is building a nine-step ramp from each brand colour where every step has a known contrast ratio against both white and black. The Contrast Palette Generator on this site spits one out for any starting colour. Once you've got it, you know which steps are safe for body text, which only work for large text, and which can only ever be backgrounds. Form fields are where 1.4.11 catches people out. The default look most design tools give you is a one-pixel border in a subtle grey that doesn't make 3:1. Same story for icon-only buttons leaning on a faint outline. Run a contrast check on every interactive component, not just text on backgrounds. For 1.4.1: anytime you mark something as an error, success, required field, status, or chart series — colour alone won't cut it. Pair it with an icon and a text label. Someone with red-green colour blindness can't tell your red badge from your green one, so the icon and the words have to be doing the actual communication.
Common pitfalls
- Brand greys used for body text or form labels because they 'look softer'. Soft greys fail 4.5:1 most of the time.
- Required fields marked with nothing but a red asterisk. Colour-blind users get no signal at all. Put the word 'required' in the label, or use `aria-required` alongside a visible cue.
- Charts that separate data series only by colour. If your line chart is unreadable in greyscale, it's unreadable for a colour-blind user too. Add dashed lines, patterns, or just label the series directly.
How to verify it
Run every text/background combination through a contrast checker. Don't trust your own eyes on this — even designers who do contrast work for a living get surprised by what fails. Watch out for text on top of images, text on gradients, and disabled-state text. Then flip the whole page to greyscale. macOS: System Settings → Accessibility → Display → Colour Filters → Greyscale. Windows: Settings → Accessibility → Colour Filters. If you can no longer tell what's interactive, what's an error, or what's a status, the design is leaning on colour too hard. Finally, run a colour-blindness simulator over the page for the four main types — deuteranopia, protanopia, tritanopia, achromatopsia. Anything that becomes ambiguous needs a second visual signal.
AccessibilityRef tools that help
- Colour Contrast Checker— test any two colours against WCAG AA and AAA
- Contrast Palette Generator— build a 9-step accessible palette from one brand colour
- Colour Blindness Simulator— preview your design under four types of colour vision deficiency
Typography and reading
How text behaves when a user starts changing the settings is part of your design, even if you never personally see those settings.
What the law says
Three criteria do most of the work. 1.4.4 (Resize Text) says text has to scale up to 200% without losing anything. 1.4.10 (Reflow) says the page needs to work at 320 CSS pixels wide with no horizontal scrolling, unless two-dimensional layout is genuinely essential. 1.4.12 (Text Spacing) says users have to be able to crank up line height, paragraph spacing, letter spacing and word spacing without your layout falling apart. Put all three together and your typography needs to survive a fair amount of user customisation. EN 301 549 Chapter 9 brings all three forward straight from WCAG.
What it means in practice
Use relative units for text sizes — rem, em, percentages. Never px. The user's browser font-size setting is your baseline, and the moment you override it with px you've taken their ability to scale away from them. Body text should be at least the 16px equivalent. Anything smaller is fine for captions and metadata, but don't drag body copy below it. Line height matters more than most designers think. WCAG 1.4.12 sets the floor at 1.5 for paragraphs, and below that dyslexic readers and low-vision users start losing their place between lines. The same criterion puts paragraph spacing at 2× the font size, letter spacing at 0.12×, and word spacing at 0.16×. Line length is its own problem. Comfortable reading caps out around 80 characters per line, roughly 65 for body text. Wider than that and you're asking the reader to do tracking work that should be design work. It isn't a WCAG criterion as such, but it matters a lot for cognitive accessibility. Reflow (1.4.10) is the one that catches older codebases. Your layout needs to work at 320 CSS pixels wide with no horizontal scrolling — roughly what 400% zoom looks like on a 1280px desktop. Fixed-width sidebars, multi-column layouts that don't collapse, tables that can't linearise — all of those will fail. Modern responsive designs usually sail through. Anything older needs a real check.
Common pitfalls
- Font sizes set in `px` instead of `rem`. This quietly steamrolls the user's browser preference and fails 1.4.4.
- Designing at a 1.2 line-height because it 'looks tighter'. Anything below 1.5 fails 1.4.12 for paragraph text.
- Sidebars or modals locked at a width that forces horizontal scrolling at 320px. Direct 1.4.10 fail.
How to verify it
Load the page at a normal width and zoom to 200%. Nothing should get cut off, a horizontal scrollbar shouldn't appear (data tables and code blocks are the usual exceptions), and you should still be able to use everything. Now set the viewport to 320 pixels wide in dev tools and reload. Same test: nothing cut off, no horizontal scroll on body content, every control still usable. That's 1.4.10 in action. For 1.4.12 text spacing, there's a bookmarklet that injects the test stylesheet — line-height 1.5, paragraph spacing 2×, letter-spacing 0.12em, word-spacing 0.16em. Run it on every page and hunt for anything clipped, overflowing, or stacked on top of itself.
AccessibilityRef tools that help
- Readability Checker— Flesch-Kincaid scoring for paste-in text
- WCAG 2.2 Audit Checklist— covers all three text-related success criteria
Touch targets, hit areas, and pointer accessibility
If a user with shaky hands or a stylus can't reliably hit your buttons, every other clever thing in your design is decoration.
What the law says
WCAG 2.2 brought in 2.5.8 (Target Size Minimum), which says pointer targets need to be at least 24×24 CSS pixels, with a small list of exceptions. The older 2.5.5 (Target Size — Enhanced) is the AAA version at 44×44. EN 301 549 v3.2.1 promoted 2.5.8 to a Level AA requirement, so it's mandatory for EAA compliance. On mobile, the platform guidelines are tighter than the WCAG floor anyway. iOS Human Interface Guidelines say 44×44 points. Material Design says 48×48 dp. Treat those as your actual minimum.
What it means in practice
The 24×24 CSS pixel minimum sounds small because it is. Treat it as the floor and aim for 44×44 wherever it actually matters. The 2.5.8 exception is that smaller targets are allowed if there's enough spacing around them so the centres of adjacent targets are at least 24px apart. A row of small icon buttons is fine, as long as you space them properly. The trap is dense data tables and toolbars. A 16×16 close button sitting next to fifteen other tiny icons fails 2.5.8 because the centres are too close together. Either make the icons bigger or pull them further apart. Good news on hit areas: the visible button doesn't have to fill the whole tap target. You can put a small visible icon inside a much larger padded area and the padding counts. That's the standard pattern for nav and toolbar buttons — CSS `padding` does the work. What you can't do is leave a tiny visible button with no padded hit area in a spot where people with motor impairments are expected to reach it. Don't forget hover and focus targets. A tooltip that pops up on hover and then vanishes the second the cursor drifts away fails 1.4.13 (Content on Hover or Focus). Tooltips have to be dismissible, hoverable, and stick around long enough to be read.
Common pitfalls
- Tightly packed icon toolbars with 16px tap targets. Steady-handed users miss them. Anyone with motor difficulties can't use the product at all.
- Tooltips that vanish the moment the cursor leaves the trigger, before the user has time to actually read what the tooltip says. Direct 1.4.13 fail.
- Fixed pixel sizes in mobile apps that ignore the platform's text-size setting. Small buttons stay small, the larger text just overflows.
How to verify it
Either use your design tool's measurement feature or pop the rendered page open in DevTools and inspect each interactive element. Anything under 24×24 CSS pixels is a fail unless it has enough breathing room around it. Anything under 44×44 deserves a closer look. For a faster sweep, the Touch Target Tester on this site lets you upload a screenshot and overlays the WCAG minimums on top of it. Handy in design review when you want to catch problems before they reach code. For mobile, test on a real device with the system text size cranked to the largest setting. Buttons that fit at default text size sometimes stop fitting at large text size, and shrinking to fit isn't an option.
AccessibilityRef tools that help
- Touch Target Tester— measure tap targets against WCAG 2.5.5 and 2.5.8
- Mobile Accessibility Checker— upload a mobile screenshot for analysis
Focus indicators and state visibility
Most designers inherit focus styles from whatever defaults the framework ships, and end up shipping a product where keyboard users are flying blind. Please don't.
What the law says
2.4.7 (Focus Visible) says any keyboard-operable interface needs a mode where the focus indicator is actually visible. WCAG 2.2 added 2.4.11 (Focus Not Obscured Minimum), which says the focused element can't be entirely hidden behind sticky headers, cookie banners, or anything else you've layered on top of the page. 2.4.13 (Focus Appearance) sets the bar for the indicator itself: a 2px solid outline at minimum, 3:1 contrast against everything next to it. All three are AA requirements under EN 301 549 v3.2.1, so they're mandatory under the EAA.
What it means in practice
Design a focus indicator on purpose. Don't let it default to whatever the browser shows after your CSS reset has had its way. Pick a colour with 3:1 contrast against every background it might land on, including hover states and dark mode. Pick a thickness that's visible without screaming — 2 to 3 pixels usually lands in the sweet spot. The pattern that works for most design systems is a high-contrast outer ring (2px) with an offset (2px), giving you a halo that stays visible whatever the underlying element looks like. CSS `outline` with `outline-offset` handles it in a single declaration. If you want more control, do it with two layers of `box-shadow` instead. For 2.4.11, if you've got a sticky header, sticky footer, or a permanent cookie banner, the focused element can't end up completely hidden behind any of them. The fix is `scroll-margin-top` on focusable elements, set to the height of whatever's sticking. The browser then scrolls the focused element into view with the right offset built in. One more thing: don't strip focus indicators from mouse users with `:focus-visible`. That pseudo-class only applies the style when focus came from a keyboard, so mouse users don't see the focus ring on click. That's the right behaviour and the modern correct way to scope focus styles.
Common pitfalls
- `outline: none` in a reset with nothing put back. This is probably the single most common WCAG failure across both developers and designers.
- A focus ring with 2:1 contrast against the page background. Looks fine on your calibrated monitor. Disappears for a low-vision user on a phone in sunlight.
- Sticky headers that bury focused inputs the moment a user tabs into them. The user is now typing into a field they can't see and giving up.
How to verify it
Tab through every page and watch the focus indicator. It should be visible on every interactive element, in every state, never hidden behind sticky UI. Watch dark mode in particular — focus styles that work fine on white often vanish on dark backgrounds. Run a contrast checker on your focus ring against every background it might land on, including button surfaces, card backgrounds, and the page itself. 3:1 is the minimum. For 2.4.11, find a long page with a sticky header, scroll most of the way down, then tab into a focusable element near the top of the viewport. The page should scroll automatically so the element clears the header. If it doesn't, add `scroll-margin-top` equal to the header height.
AccessibilityRef tools that help
- Focus Order Visualiser— see exactly where focus lands and in what order
- Contrast Checker— test focus ring contrast against backgrounds
Further reading
Motion, animation, and reduced-motion preferences
Animation is a feature for some users and a barrier for others. The operating system already knows which is which. Listen to it.
What the law says
2.3.1 (Three Flashes or Below Threshold) bans content that flashes more than three times per second, because it can trigger seizures in photosensitive users. 2.2.2 (Pause, Stop, Hide) says anything moving, blinking, or auto-updating for more than five seconds needs a way for the user to pause, stop, or hide it. WCAG 2.1 added 2.3.3 (Animation from Interactions) at AAA, which is where `prefers-reduced-motion` formally lives — it says motion triggered by interaction has to be disablable. The EN 301 549 web clauses bring all of those forward.
What it means in practice
Use animation deliberately, not as decoration. A 200ms fade on a tooltip is fine. A 600ms parallax scroll on every section of every page is going to make some users physically sick. Vestibular disorders affect something like one in three adults at some point in their lives — that's a much bigger group than most designers think. One rule covers most of this: respect `prefers-reduced-motion`. macOS and iOS have a 'Reduce Motion' setting. Windows and Android have their own version. The CSS media query `@media (prefers-reduced-motion: reduce)` lets you switch off or shorten any animation when the user has signalled they want less of it. Don't kill animation entirely when reduced motion is on — that often breaks expected feedback like menu transitions. The pattern is: keep functional micro-animations (50-200ms hover, focus, state-change transitions) and switch off the decorative stuff (parallax, autoplay video, large transforms, looping animations). Never autoplay video with sound. Never use a carousel that auto-advances with no pause control. Both fail 2.2.2 directly. If you absolutely have to have a hero video, make it muted, looping, decorative, and give it a pause button anyway.
Common pitfalls
- Parallax scrolling that ignores `prefers-reduced-motion`. Common cause of vestibular distress.
- Auto-advancing carousels with no pause button. Direct 2.2.2 fail.
- Hover animations clocking in at 500ms or more. They feel sluggish, the interface feels laggy, and you've shut out anyone who needs fast feedback.
How to verify it
Turn on Reduce Motion in your OS settings (macOS: System Settings → Accessibility → Display; Windows: Settings → Accessibility → Visual effects). Reload the site. Decorative animations should be gone or shortened. Functional micro-animations should still work. For flashing content (2.3.1), the safest answer is to not ship anything that flashes at all. If you've got a strobe effect, a video with hard cuts, or a loading spinner that flickers, run it through PEAT (Photosensitive Epilepsy Analysis Tool) before it goes live. For auto-advancing content, the question is straightforward: can the user pause it? 'Eventually, if they hover for long enough' is not an answer. There has to be a clearly visible pause control.
AccessibilityRef tools that help
- WCAG 2.2 Audit Checklist— covers all motion-related success criteria
- Cognitive Accessibility Checklist— additional cognitive load considerations for motion
Further reading
Important Legal Disclaimer
This tool is a self-assessment aid only and does not constitute legal advice or a formally certified compliance assessment. Outputs — including reports, scores, checklists, and accessibility statements — are for internal use and should be reviewed by a qualified legal representative or independent accessibility auditor before being relied upon for regulatory, procurement, or public-disclosure purposes. All assessment risk lies with the internal assessor. accessibilityref, its developers, and staff accept zero liability for losses arising from use of or reliance on these outputs. Always verify against official sources: the W3C WCAG 2.2 Recommendation, the European Accessibility Act (Directive 2019/882), and your national enforcement authority.