Skip to main content

Our email CSS engine is open source. Give it a star on GitHub 

Emailens
Blog

Email Accessibility: 8 Fixes for Screen Readers and Contrast

An accessible HTML email sets lang on <html>, marks layout tables role="presentation", gives every image alt text (empty for decoration), keeps text at 4.5:1 contrast, uses descriptive link text and real headings, holds that contrast in dark mode, and is checked with a screen reader such as VoiceOver or NVDA.

The checker needs a computer screen.

A free account opens all 21 clients and keeps your checks for 7 days. Create a free account →

Philippe Kam, founder of Emailens · Published 4 Mar 2026 · Updated 8 Nov 2026

@emailens/engine 0.18.22 · data last changed 10 Nov 2026

Part of the HTML email guide · all guides

A password reset, a receipt or a delivery notice that a reader cannot read is a support ticket, a lost order or a reader who unsubscribes. The fixes below are specific to email, where your HTML is rewritten by the client before anyone reads it. Most take a minute.

Eight fixes for an accessible HTML email

1. Set lang and dir, twice

lang picks the screen reader's voice and pronunciation; dir sets reading order for Arabic and Hebrew. Put both on <html>, and again on the outer wrapper. Some clients remove the email's <html>, <head> and <body> and keep only what is inside, which takes the attribute with it. Yahoo and AOL also ignore lang on a <td>, so use a <div> or <table> for the wrapper.

Set lang and dir, twice
6 lines
<html lang="fr" dir="ltr">
<body>
  <div lang="fr" dir="ltr" style="direction: ltr;">
    …
  </div>
</body>

2. Put role="presentation" on every layout table

Without it, a screen reader can announce "table, 3 columns, 5 rows" before your headline, and again for each nested table. Data tables, such as an order summary, keep their table semantics and get <th> headers instead.

Put role="presentation" on every layout table
<table role="presentation" width="100%" cellpadding="0" cellspacing="0" border="0">

3. Write alt text that works when images are off

Some readers have images turned off, and some clients wait for a click before they load them. The alt text is then what shows in the image's place, so it must carry the message: the offer, not the file. Decorative images get alt="". A logo gets the company name.

Write alt text that works when images are off
5 lines
<!-- Bad: a filename, or a description of the picture -->
<img src="hero-v3.jpg" alt="hero-v3.jpg">

<!-- Good: what the image says -->
<img src="hero.jpg" alt="Autumn sale: 30% off coats until Sunday" width="600" height="300">

4. Keep the message in HTML text

An email built as one image is empty to a screen reader and blank when images are off. Put headlines, prices, dates and buttons in live text. A button should be a link styled as a button, not a picture of one.

5. Check contrast in light and dark mode

WCAG 2.2 AA asks for 4.5:1 for body text and 3:1 for text at 24px, or about 18.7px bold. Mid grey #666666 on white is 5.74:1 and passes. Dark mode changes your colours without asking: see the next section.

6. Size text and tap targets for phones

WCAG sets no minimum font size, but 14 to 16px body text reads on a phone without zooming. Below 13px, mail apps built on WebKit or Blink can enlarge text in multi-column layouts and break the layout; add -webkit-text-size-adjust: 100% to the body. WCAG 2.2 asks for tap targets of at least 24 by 24px (AA) and recommends 44 by 44px (AAA): pad the link, not only the cell around it.

Size text and tap targets for phones
<a href="https://acme.com/track" style="display: inline-block; padding: 14px 24px; font-size: 16px;">Track your order</a>

7. Write link text that makes sense alone

Screen reader users jump from link to link, so each one is read without the sentence around it. "Click here" and "Read more" say nothing. Name the destination.

Write link text that makes sense alone
5 lines
<!-- Bad -->
<a href="/pricing">Click here</a>

<!-- Good -->
<a href="/pricing">See the pricing plans</a>

8. Use real headings, in order

Screen reader users skim by heading. One <h1> for the email's subject, <h2> for each section, and no jumps from <h1> to <h3>. Style the headings inline; a <p> made bold and large is not a heading to a screen reader.

Which clients keep lang and role

An attribute only helps if the client leaves it in place. From the Emailens engine's support data:

  • lang: Works in 15 of 21. Yahoo Mail and AOL drop it on a <td>; HEY drops it.
  • role: Works in 14 of 21. Yahoo Mail and AOL keep it on a <table> only, which is where layout needs it. Outlook Classic and HEY drop it.
  • dir: Works in 19 of 21. Outlook Classic is unreliable on a link, so set the direction on the block around it.

Dark mode changes your contrast for you

A colour pair that passes in light mode can fail once the client recolours it. Two clients we measured on the real app:

  • Gmail on Android flips the lightness of text darker than a set brightness, and of light backgrounds. White becomes #121212. Mid-tone text gets darker, not lighter: green #16a34a becomes #008e37, 4.39:1 on that background, under the 4.5:1 line. Our model of this rule agreed with the real app's contrast verdict on all 424 colour pairs held out to test it (31 October 2026).
  • Outlook for Mac moves every background with any hue to the same lightness. In one email, a cream card, the beige page around it and a near-black header all came out as about #53514d (3 November 2026). A card that relied on its background to stand out loses its edge; give it a border too.

Colours near the middle of the range move the most. Check mid-tone text and coloured buttons in a dark mode preview before you send.

The hidden preheader is hidden from screen readers too

The preview text after the subject line usually comes from a display: none element at the top of the body. display: none removes it from what a screen reader reads, so a reader using one never hears it. Keep anything important in the visible body as well.

How to test email accessibility

Run an automated check first, then listen to the email in a real client:

  1. Paste the HTML into the accessibility checker. It flags a missing lang or <title>, images with no alt or a file name as alt, links with no name or generic text, layout tables without role, text under 9px, low contrast and skipped heading levels.
  2. Send the email to yourself and open it in the webmail and apps your readers use. The client's own markup surrounds yours, so a browser preview of the raw HTML is not the same test.
  3. Read it with a screen reader: VoiceOver on Mac and iPhone, TalkBack on Android, NVDA (free) or JAWS on Windows. Check that the order makes sense, tables are not announced, every image is described or skipped, and every link says where it goes.

Questions

Why do HTML email layout tables need role='presentation'?

A screen reader announces a <table> as a data table, with its row and column counts, and may read cell positions. role='presentation' tells it the table is layout only, so it reads the content in order. Put it on every layout table, nested ones included.

What is the minimum contrast ratio for email text?

WCAG 2.2 AA asks for 4.5:1 for body text and 3:1 for large text, which is 24px, or about 18.7px when bold. Check dark mode too: Gmail on Android darkens mid-tone text, so green #16a34a becomes #008e37, 4.39:1 on Gmail's dark background.

Should decorative images in emails have an alt attribute?

Yes, an empty one: alt=''. With no alt attribute at all, some screen readers read the file name or the image URL. A spacer, a divider or a corner image gets alt=''.

Is the hidden preheader read by screen readers?

No. A preheader hidden with display:none is hidden from screen readers too. Put nothing in it that the reader needs and that the body does not also say.

Your next question

Also useful: Accessibility Checker · Dark Mode Preview · Email Link Checker

Paste the email that broke.

The checker needs a computer screen.

Get new email CSS fixes by email, or follow by RSS.