Français

Three bills, one codebase, zero overhead

Table of contents

The common foundation

In 1997, Tim Berners-Lee, the inventor of the World Wide Web, launched the W3C's accessibility initiative with these words: "The power of the Web is in its universality. Access by everyone regardless of disability is an essential aspect."

Nearly thirty years later, that universality has three names in engineering teams: accessibility, performance, and SEO. Three scores in Lighthouse. Three columns in dashboards. Three budgets in project plans. Three teams that often work in silos.

Except all three rest on the same foundation: clean, semantic, lightweight HTML. The practices that make a site accessible also make it fast. The practices that make it fast also make it indexable. And the practices that make it indexable also make it accessible.

The reverse is equally true: every shortcut that degrades one degrades the other two. A <div> styled as a button? The screen reader doesn't understand it (accessibility), the browser loads extra JavaScript to make it work (performance), and the crawler doesn't know it's an interactive element (SEO). One bad choice, three bills.

The same HTML, three wins

Semantic HTML is where the three disciplines converge. Every native element used correctly simultaneously serves accessibility, performance, and SEO. Without a single extra line of code.

Headings

headings.html
<!-- ❌ A styled div — invisible to all three -->
<div class="big-bold-text">Our pricing</div>
 
<!-- ✅ An h2 — visible to all three -->
<h2>Our pricing</h2>

The <h2> is announced by the screen reader as a level 2 heading. The user can jump to it with a keyboard shortcut. The browser renders it natively without JavaScript or extra CSS. Google uses it to understand the page structure and extract featured snippets. The LLMs that power GEO use it to structure their answers.

The <div> styled in bold? None of the three sees a heading.

Landmarks

landmarks.html
<header>...</header>
<nav aria-label="Main navigation">...</nav>
<main>...</main>
<aside>...</aside>
<footer>...</footer>

Five HTML elements. The screen reader announces them as navigable regions. The browser renders them without scripts. Google recognizes the page structure: main content in <main>, navigation in <nav>, secondary content in <aside>. Every <div> removed for styling purposes, every CSS class carried directly by a semantic element lightens the DOM, speeds up rendering, and enriches both the accessibility tree and indexation.

Buttons

A <button> costs 0 bytes of custom JavaScript to work with keyboard, click, touch, and screen reader. A <div role="button" tabindex="0"> with a click handler, a keydown handler for Enter and Space, and manual focus styling costs dozens of lines. And remains less reliable on all three axes.

Images, triple stakes

We saw in the two lives of an image how alt text serves accessibility. But every attribute on an image also serves performance and SEO:

image-triple.html
<img
  src="product.webp"
  alt="Over-ear wireless headphones, cushioned ear cups, matte black"
  width="800"
  height="600"
  loading="lazy"
>
How image attributes serve all three axes
AttributeAccessibilityPerformanceSEO
altScreen reader describes the imageText displays if image doesn't loadGoogle indexes the content, LLMs cite it
width / height—Browser reserves space → zero layout shift (CLS)—
loading="lazy"—Offscreen images load on scroll → better LCPCrawl uses less bandwidth
WebP/AVIF format—Lighter file → faster loadingGoogle recommends modern formats

Four attributes. Zero JavaScript. All three scores improve.

The hidden cost of JavaScript

Every time JavaScript modifies the DOM, the browser recalculates three things: visual rendering, layout, and the accessibility tree. On mobile, the reality for 60% of global web traffic, especially on less powerful devices and less reliable connections, every recalculation costs time.

A site that loads 2 MB of JavaScript to display a static page pays three times:

  • Performance: the browser parses, compiles and executes the script before displaying anything. LCP explodes.
  • Accessibility: the screen reader waits for the accessibility tree to stabilize. Meanwhile, the user hears either nothing or an incoherent intermediate state.
  • SEO: the crawler has a limited rendering budget. The heavier your JavaScript, the more likely it indexes an empty or incomplete page.

The solution isn't to ban JavaScript. It's to use it as an enhancement layer, not a foundation. Progressive enhancement and server-side rendering (SSR) ensure that complete HTML reaches the browser: the screen reader can read immediately, the search engine indexes real content, and the user sees the page before JavaScript finishes loading.

User preferences

CSS offers media queries that detect user preferences at the operating system level. Each one serves accessibility and performance:

prefers-reduced-motion: the user has disabled animations in their system settings. It could be a vestibular disorder, epilepsy, migraine, or simply a low-end device that struggles with CSS animations. Rather than removing animations after the fact, the best approach is to only enable them for those who want them:

motion.css
/* Only if the user accepts animations */
@media (prefers-reduced-motion: no-preference) {
  .card {
    animation: fade-in var(--duration) ease-out;
  }
}

The visual result is the same for those who accept animations. But for everyone else, the browser has nothing to calculate. No animation created then overridden. Less CSS, fewer calculations, accessible and performant from the start.

prefers-contrast: the user requests enhanced contrast. It's a visual accessibility need, but it's also an indicator that the user may be browsing in degraded conditions. A screen in direct sunlight or an aging monitor, for example.

prefers-color-scheme: dark mode reduces screen brightness, decreases eye strain, and on OLED screens, reduces battery consumption. Accessibility, comfort, and hardware performance in a single media query.

These three settings already exist in your users' systems. You just need to listen.

Measuring all three at once

Open Lighthouse in your browser's developer tools (F12 → Lighthouse tab). Run an audit. In a single pass, you get four scores: Performance, Accessibility, Best Practices, SEO.

The issues that tank one score often tank the others:

  • Images without alt → accessibility score drops, SEO score too. Be careful not to stuff alt with keywords on decorative images though, that's hidden text for Google.
  • Images without dimensions → CLS rises: the performance score drops, and Google ranking with it (Core Web Vitals)
  • Headings that skip levels → the accessibility score drops, and the structure becomes unreadable for crawlers
  • A DOM that's too deep, <div> elements nested ten levels deep just to position an element → accessibility tree recalculation slows down (performance) and the crawler gets lost in the structure (SEO)

One audit, three diagnoses. And the fixes are often the same. Semantic HTML, complete attributes, less JavaScript.

Lighthouse doesn't replace testing with a screen reader, a deep SEO audit, or a load test. But it's the first warning signal and it shows at a glance that the three disciplines converge.

Sources