DEV Community

Soumaya Erradi
Soumaya Erradi

Posted on

The European Accessibility Act: What developers need to know

The European Accessibility Act (EAA) is about to change the game, starting June 28, 2025, digital accessibility becomes mandatory for products and services offered to EU users.

If you’re a developer building websites, mobile apps, or digital tools for the European market, accessibility is no longer a best practice, it’s a legal requirement.

In this article, we’ll cover what that means for you, with real code examples you can apply today. Let’s dive in.


What’s the EAA?

The European Accessibility Act is an EU directive designed to harmonize accessibility standards across Europe. Its goal is to ensure that people with disabilities can access and use digital products and services on equal terms.

As of June 28, 2025, all businesses offering digital products or services to EU consumers, even if they're based outside the EU, must comply with these rules.

The law applies to:

  • Websites and mobile apps
  • E-commerce platforms
  • Banking, ticketing, and transport services
  • eBooks, self-service terminals, ATMs, and more

The EAA is based on:

  • WCAG 2.1 AA (Web Content Accessibility Guidelines)
  • EN 301 549, a European standard for ICT accessibility

National authorities will be responsible for enforcing compliance, which means audits, penalties, and reputational risks for companies that fail to meet the bar.

Bottom line: You need to ensure your digital interfaces are usable by everyone, starting now.


Accessibility is a fix, not a feature

“An app without keyboard support or labels is broken for many users.”

Accessibility ensures people with visual, motor, cognitive, or situational impairments can use your product. Let’s fix common issues.


Forms: always pair inputs with labels

Screen readers need labels to announce fields.

❌ Missing label:

<input type="email" placeholder="Email">
Enter fullscreen mode Exit fullscreen mode

✅ Proper label:

<label for="email">Email</label>
<input id="email" type="email">
Enter fullscreen mode Exit fullscreen mode

🔁 Alternative:

<input type="email" aria-label="Email">
Enter fullscreen mode Exit fullscreen mode

Icon buttons: provide an accessible name

Icon-only buttons must expose a name.

❌ Unlabeled:

<button><i class="fa fa-search"></i></button>
Enter fullscreen mode Exit fullscreen mode

✅ With aria-label:

<button aria-label="Search">
  <i class="fa fa-search"></i>
</button>
Enter fullscreen mode Exit fullscreen mode

Images: never skip alt

Screen readers ignore images without alt.

❌ No alt:

<img src="logo.png">
Enter fullscreen mode Exit fullscreen mode

✅ Descriptive alt:

<img src="logo.png" alt="Company logo">
Enter fullscreen mode Exit fullscreen mode

Decorative?

<img src="divider.svg" alt="">
Enter fullscreen mode Exit fullscreen mode

Keyboard: make everything tabbable

Test your UI without a mouse. If you can’t Tab to it, users can’t either.

✅ Native button:

<button>Submit</button>
Enter fullscreen mode Exit fullscreen mode

❌ Div hack:

<div onclick="submitForm()">Submit</div>
Enter fullscreen mode Exit fullscreen mode

If you must use a div:

<div role="button" tabindex="0"
     onclick="submitForm()"
     onkeydown="if(event.key==='Enter') submitForm()">
  Submit
</div>
Enter fullscreen mode Exit fullscreen mode

but prefer <button>.


Headings: maintain hierarchy

Headings create an outline for screen reader users.

❌ Wrong:

<h1>Dashboard</h1>
<h4>Stats</h4>
Enter fullscreen mode Exit fullscreen mode

✅ Right:

<h1>Dashboard</h1>
<h2>Stats</h2>
Enter fullscreen mode Exit fullscreen mode

Contrast: verify ratios

Ensure text/background contrast meets WCAG:

  • 4.5:1 for normal text
  • 3:1 for large text (≥18px bold)

Use tools like:


Automate with tools

Catch many issues early—automate these checks:

🧪 Lighthouse (Chrome DevTools)

Inspect → Lighthouse → Accessibility

🧪 axe-core

npm install --save-dev axe-core
Enter fullscreen mode Exit fullscreen mode
import axe from 'axe-core';
axe.run(document).then(({ violations }) => {
  console.log(violations);
});
Enter fullscreen mode Exit fullscreen mode

🧰 Other integrations

  • Pa11y (CLI)
  • Playwright + @axe-core/playwright
  • Cypress + cypress-axe

Dynamic content

After a route change or modal open, re-run your checks and manage focus.

Playwright example:

import { injectAxe, checkA11y } from '@axe-core/playwright';

await injectAxe(page);
await page.click('#open-modal');
await checkA11y(page, '#modal-content');
Enter fullscreen mode Exit fullscreen mode

Focus management:

const dialog = document.querySelector('[role="dialog"]');
dialog.hidden = false;
dialog.focus();
Enter fullscreen mode Exit fullscreen mode

ARIA live for updates:

<div aria-live="polite" id="status">3 items added to cart</div>
Enter fullscreen mode Exit fullscreen mode

Quick dev checklist

  • Labels on all form controls
  • Icon buttons have aria-label
  • Images include meaningful alt
  • Keyboard navigation works
  • Logical heading order
  • Sufficient color contrast
  • Dynamic changes announced

Conclusion

The EAA is weeks away from enforcement, and for developers, this is a pivotal moment. Accessibility is now part of your delivery requirements, not something to push down the backlog.

Start reviewing your apps with real users in mind. Write accessible HTML, automate your checks, and fix the easy stuff first. Tools can help, but so can habits.

Because in the end, accessibility isn’t just about compliance, it’s about building better software for everyone.

Top comments (0)