BLOG · DRUPAL · EAA

Drupal Accessibility:
Meeting WCAG 2.1 AA and the EAA

A practical guide for agencies building Drupal sites for EU clients — what core already does well, where contributed modules break compliance, and how to verify before the EAA bites.

Updated August 2026 · Reading time: 7 minutes

drupal-core-accessibility

Drupal has one of the strongest accessibility foundations of any CMS. Since Drupal 8, core conforms to WCAG 2.1 and ATAG 2.0 as a policy goal: the Olivero front-end theme ships accessible by default, form elements render labels programmatically tied to inputs, and core JavaScript uses the Drupal behaviours system to keep ARIA state consistent after AJAX updates. Claro, the admin theme, is built to the same standard. If your site is core-plus-Olivero with no heavy customisation, you start from a genuinely good baseline — most of your remaining risk comes from what gets layered on top.

🏗️ Core Baseline

Semantic markup, labelled forms, focus management and ARIA live regions are handled at the theme-system level, not left to each site builder.

🎨 Olivero & Claro

The default front-end and admin themes both target WCAG 2.1 AA, including a mobile navigation with proper disclosure semantics and visible focus states.

⚙️ ATAG 2.0

Drupal aims beyond content output: the editing experience itself is accessible, which matters for public-sector procurement under EN 301 549.

where-drupal-sites-fail

Real-world Drupal accessibility failures concentrate in four places — almost never in core:

🧩 Contributed Modules

Modules that render their own markup (sliders, calendars, menus, payment widgets) bypass the theme system. Quality varies enormously; some ship decade-old jQuery patterns with unlabelled controls.

🖼️ Content Editor Habits

Missing alt text on images uploaded through the media library, headings chosen for visual size, links that just say "read more". The editor toolbar is accessible; the habits often are not.

🎛️ Views & Custom Blocks

Views-generated lists can produce empty headings or repeated identical link text across rows. Custom block types frequently skip heading levels.

💻 Custom Themes

Hand-rolled or heavily customised themes reintroduce every classic failure: placeholder-only inputs, divs-as-buttons, contrast set from a brand palette without checking ratios.

contrib-module-audit

Treat every contributed module that renders front-end UI as guilty until scanned:

Inventory: list modules that output markup on public pages (sliders, maps, video players, booking widgets, newsletter forms). Anything only used in the admin can wait.

Scan each widget: tab through it on a real page. Unlabelled icon buttons, keyboard traps and missing focus indicators are disqualifying — look for an alternative module or patch the issue queue upstream.

Check updates: many accessibility patches already exist in newer releases. Running current stable versions of contrib is itself an accessibility measure.

WYSIWYG settings: limit CKEditor 5 buttons so editors cannot inject inline colours or fonts that break contrast and structure. Fewer tools, more compliant content.

views-forms-and-content

Three high-volume fixes that cover most findings on a typical build:

Views: give every display a real, unique title instead of relying on auto-generated empty headings; use distinct link text per row ("Read the case study" not "Read more"); check pager markup announces current page.

Forms: webform and contact forms label fields correctly out of the box — failures come from custom alterations. Verify required-field indication is not colour-only, and error messages are text, not red borders alone.

Content: enforce alt text via the media library (it is required by default — do not weaken it), train editors on heading order, and add a "link text" guideline to your editorial checklist.

Multilingual: lang attributes on translated pages must switch with the interface translation — Drupal handles this in core, but custom routes and embedded content frequently forget it.

verification-workflow-drupal

A realistic verification loop for a Drupal build takes half a day:

Step 1 — automated scan of home, a listing page, a node page, a form page and search results. Expect 5-15 mechanical findings on the first run, mostly content and contrib.

Step 2 — fix and re-scan until automated findings clear: theme CSS, Views titles, alt text backfill.

Step 3 — keyboard walkthrough of search → listing → node → form submit. Anything mouse-only fails WCAG 2.1.2.

Step 4 — screen reader spot-check of one full journey with NVDA or VoiceOver, listening for unlabelled controls and silent AJAX updates.

Step 5 — re-run after every module update and new block type. Regressions arrive silently with contrib updates.

Going Deeper

Run the free scanner on your front-end first — it catches contrast, alt-text, label and heading issues in seconds, so your expert time goes on judgement calls like keyboard flows and ARIA.

Scan Your Drupal Site Free → →    Drupal Guide → →

Frequently Asked Questions

Is Drupal more accessible than WordPress?

Out of the box, yes — Drupal core targets WCAG 2.1 and ATAG 2.0 explicitly, while WordPress quality depends far more on the chosen theme and plugins. But a badly customised Drupal theme loses that advantage quickly; the platform baseline helps, it does not guarantee anything.

Does the EAA apply to Drupal sites?

To the services delivered through them, when consumer-facing in the EU — including e-commerce and membership sites. Public-sector Drupal builds have long been bound by EN 301 549 procurement rules regardless.

Which contributed modules cause the most issues?

Third-party UI widgets: sliders/carousels, maps, calendar/booking widgets and legacy menu modules. They ship their own markup outside the theme system, so core guarantees stop at their edge.

Do I need Bartik or Olivero specifically?

No theme is mandatory, but starting from a maintained core theme saves weeks. If you must customise, subclass and override templates rather than forking — you keep upstream accessibility fixes on update.

How long does a Drupal accessibility pass take?

A core-plus-contrib build on Olivero: 1-3 days including testing. Heavily customised legacy themes (Bootstrap-based forks are common offenders) need a bigger remediation project.

Scan Your Drupal Site Free → →    Drupal Guide → →