Drupal has a better baseline accessibility story than most CMSes. Core's commitment to it is not a marketing line — it's a documented release-blocking requirement, audited every minor version. If you ship a stock Drupal 11 site with a maintained theme, you are starting closer to WCAG 2.2 AA than you would on almost any other platform.
That said, "starting closer" is not "passing." Every Drupal site we audit has gaps, and the gaps are remarkably consistent. This post covers what 2.2 actually requires, where stock Drupal already meets it, and the specific failures we see on real client sites — with the fixes that move them across the line.
What changed in 2.2 (and what it means for your audit)
WCAG 2.2 published in October 2023 and added nine new success criteria over 2.1. Five of them are AA-level, which is the bar most government and education clients are required to meet. The ones that actually matter for typical Drupal sites:
- 2.4.11 Focus Not Obscured (Minimum) — When an element is keyboard-focused, it can't be entirely hidden by a sticky header, modal, or other overlay. This is the one that catches most sticky-header sites the moment they're audited.
- 2.5.8 Target Size (Minimum) — Interactive controls need a 24×24 CSS pixel target. The exception clauses are narrow; assume every icon-only button needs auditing.
- 3.3.7 Redundant Entry — If you ask a user the same information twice in the same flow (a webform with a confirm-email field, for example), the second time it must be auto-fillable or auto-populated. Affects multi-step Webform builds.
- 3.3.8 Accessible Authentication (Minimum) — Users can't be required to solve a cognitive function test (math problem, image identification) to authenticate, with limited exceptions. CAPTCHA strategies need to be revisited.
- 2.4.13 Focus Appearance — Note: this is AAA in 2.2, not AA — but several state laws now reference 2.2 AA "or higher", so it's worth tracking.
If you're auditing against 2.1 today, your audit isn't current. State and federal procurement language is increasingly specifying 2.2.
Where stock Drupal already gets it right
Credit where it's due. On a fresh Drupal 11 install with Olivero (the default theme), out of the box you get:
- Semantic landmarks everywhere — every region renders proper
<header>,<nav>,<main>,<aside>,<footer>. This is invisible until you try to hand-roll it on a different platform and discover how much you took for granted. - Skip-to-main-content link — present, working, focusable. The Olivero implementation also handles the WCAG 2.2 focus-not-obscured rule by accounting for the sticky header height.
- Keyboard-navigable admin UI — Drupal's admin is more keyboard-accessible than the WordPress admin or any custom CMS we've seen. Editors with motor or vision constraints can actually do their jobs.
- Form rendering with associated labels —
Form APIautomatically associates labels with inputs and renders error messages with the right ARIA attributes. You have to actively work to break this. - Image field alt text enforcement — alt text on image fields is configurable as required. Default it to required for content types that face the public.
- Color contrast on Olivero defaults — Olivero's default palette meets AA. The trouble starts when sites override it with brand colors that haven't been contrast-tested.
This baseline is the best starting point in CMS-land. The work is not building it — the work is not breaking it.
Common failures on real client sites
Across the Drupal sites we've audited in the last year, the same five failure patterns account for the overwhelming majority of issues.
1. Custom blocks rendered without proper structure
A developer adds a custom block to a page using a paragraph type or a custom block type, and the rendered output uses <div> for everything. No headings, no list structure, no semantic landmarks. The page has 30 visual sections and one <h1>.
Fix: Use Twig templates that render the actual semantic structure. If a paragraph displays a list of cards, render <ul><li> — not <div><div>. If a section has a heading, mark it as <h2> or <h3> with proper hierarchy. Use Twig Tweak's attach_library to load section-specific styling without breaking semantics.
2. Brand colors that fail contrast
The site palette comes from a brand guideline written by a marketing agency that didn't think about accessibility. Light gray text on white. Brand-color buttons with white text where the contrast ratio is 3.5:1. Subtle hover states that disappear at 4.5:1 thresholds.
Fix: Run every brand color through the WebAIM contrast checker before locking the palette. If a brand color fails, derive a darker variant for use on text and a lighter variant for use as background — keep the original brand color for accents only. We've never had a client refuse a 5–10% darken when the alternative was failing audits.
3. Sticky header obscures focused elements (the 2.2 issue)
Sticky headers are everywhere now. The default behavior of position: sticky; top: 0; plus tabindex traversal means the focused element can scroll behind the header. WCAG 2.2 SC 2.4.11 (Minimum) says the focused element can't be entirely hidden — partial obscuring is allowed but not full hiding.
Fix: Add scroll-padding-top: <header-height> to the html element. This single CSS line tells the browser to scroll focused elements into view below the sticky header, not behind it. We add it to every theme's base CSS file as a default.
4. Webform target sizes (the other 2.2 issue)
Webform's default rendering for radio buttons, checkboxes, and small icon buttons frequently produces hit targets smaller than 24×24 pixels at standard zoom. Mobile users with motor impairments miss the target.
Fix: Add CSS to your theme that enforces minimum dimensions on form controls:
.webform-submission-form input[type="radio"],
.webform-submission-form input[type="checkbox"] {
min-width: 24px;
min-height: 24px;
}
.webform-submission-form .button,
.webform-submission-form .form-submit {
min-height: 44px; /* AAA target, easy to meet on form buttons */
}
For Layout Builder block icons or admin toolbar buttons, audit each one and add padding to bring the click area to 24×24 even when the visible icon is smaller.
5. Decorative images with alt text
The opposite of the more famous problem. A decorative background image (separator line, ornamental flourish) gets alt text like "decorative line" or even the image filename. Screen readers announce it. Users hear "image: decorative-line.png" mid-paragraph.
Fix: For purely decorative images, set alt="" (an empty string, not absent). In Drupal image fields, mark the alt text field as not required and explicitly leave it blank for decorative content. In Twig templates, ensure {{ image.alt }} doesn't fall through to filename when empty.
How we run a Drupal accessibility audit
A typical audit on a small-to-mid Drupal site is 4–6 hours of effort. The flow:
- Automated pass with axe. axe DevTools browser extension or @axe-core/playwright for CI. Runs against every page template (home, content type detail, listing pages, search, contact). Catches color contrast, ARIA misuse, missing labels, semantic structure issues. Produces a defect list grouped by rule.
- Manual keyboard test. Tab through every interactive element on the home page, content detail page, and any form. Confirm every element is reachable, focus is always visible, focus order is logical, and no element is obscured when focused. This catches things axe can't — like sticky-header-focus-obscured.
- Screen reader spot-check. VoiceOver on macOS or NVDA on Windows. Listen through the home page heading hierarchy and one form submission flow. You don't need to be fluent — you just need to verify nothing is announced as "image image link link link" gibberish.
- Mobile motor test. Tap-target audit on real mobile. We use Chrome DevTools' device emulation with touch on for the first pass and a real iPhone for the second.
- Document findings. A simple spreadsheet with each violation, the WCAG SC reference, the page where it occurs, and the proposed fix. Estimate hours per fix. Group by rule for efficient remediation.
The 4–6 hours covers the audit. Remediation usually takes 2–3× that depending on what's broken.
What government clients should know
If you're a Colorado government entity — city, county, special district, state agency — you're subject to HB21-1110, which requires WCAG 2.1 Level AA on all government technology as of July 2024. Federal procurement (Section 508) has been catching up to 2.2 throughout 2025–2026. Even where 2.2 isn't yet legally required, expecting it from your vendor is reasonable: 2.2 is the current standard, 2.1 is two versions old.
For private-sector clients, the legal threshold is Title III ADA case law, which doesn't reference a specific WCAG version but practically expects current standards. The actual risk for non-government sites is litigation, and accessibility lawsuits have been rising every year since 2018. A 2.2 AA-compliant site is the cheapest insurance available.
Our pre-launch accessibility checklist
We won't ship a Drupal site without:
- Automated axe scan with zero violations on every page template
- Manual keyboard test of all interactive elements with focus visible at every step
- Skip-link working and not obscured by sticky header
- All form controls labeled, error messages associated, target sizes ≥24×24
- Color contrast verified for every brand color used in text or interactive states
- Alt text reviewed on every image (decorative blank, content described)
- Headings audited for hierarchy and presence on every page template
- Page-load test with screen reader to catch unannounced or misannounced content
- An accessibility statement page documenting the standard met and a contact for issues
If you're a Drupal site running on Colorado's HB21-1110 timeline and you're not sure where you stand, get in touch — first audit is free.

