HTML email: Gmail auto-links, stripped buttons, lost styles

Fixing HTML email for Gmail and other clients: auto-linked addresses, stripped buttons, lost editor styles, plain-text parts and a preview that matches.

By

The HTML email Gmail shows your customer is often a little different from the one you designed. It adds links you never wrote, other clients drop styles you relied on, and your own sanitising step can throw away formatting. This post covers the HTML email fixes I made on Fotobank, a stock photo marketplace with login, welcome, reminder and admin emails, and the rules I'd carry to any product that sends mail.

Why HTML email in Gmail turns addresses into blue links

Fotobank's login email has a dark box with the support address in white text. In Gmail, that address came out as a blue link, which broke the look of the box.

Gmail spots anything that looks like an email address in plain text and wraps it in its own link, with its own colour. Your CSS for the surrounding text does not reach that link, because Gmail created it after your styles were written.

The fix is to get there first. Write the address as a real mailto: link styled in the site's own colours, and Gmail leaves it alone:

<a href="mailto:support@example.com"
   style="color:#ffffff; text-decoration:underline;">support@example.com</a>

The same thing happens with phone numbers, dates and street addresses in some clients. If a piece of text sits on a coloured background, assume a client might turn it into a link, and style it as one yourself.

Keep a plain link under every styled button

Login emails have a big styled button. Some email clients strip styled buttons, or render them as an unstyled bit of text that does not look clickable. So under the button, every Fotobank login email also has a plain link with the same URL.

It looks redundant, and it saves the person whose client ate the button. Email buttons in Outlook on Windows are the classic case: its desktop versions render HTML with a word-processor engine that ignores a lot of CSS, including padding on links, so a button built from a padded <a> can shrink to a bare link. Litmus has a good guide to bulletproof email buttons that compares the table, padding and border techniques. A plain text link reads the same in every client.

My default for buttons:

  • Build the button as a link inside a table cell with a background colour, which survives more clients than padding on the link alone.
  • Put the URL in text under it, with a short line such as "Or open this link".
  • Keep the button's label in words a person would click: "Log in", "View your cart".

Email-safe HTML without throwing away the editor's styles

Admin emails on Fotobank are written in a rich text editor. Before sending, an email-safe pass adds inline styles to tags, because many clients ignore <style> blocks and classes. Gmail's own support is documented in its CSS support reference, and inline styles remain the safest bet across clients.

The first version of that pass replaced the style attribute on p, heading and ul tags outright. Anything the writer had set in the editor, such as centred text or a coloured heading, was gone in the sent email.

The fix relies on how inline styles resolve: when the same property appears twice in one style attribute, the later one wins. So the pass now puts its defaults in front of the editor's own style, and the editor's choices override them. Images are the exception: max-width goes last, so nothing the writer set can push an image wider than the email.

function withDefaults(defaults: string, own: string | null): string {
  return own ? `${defaults}; ${own}` : defaults;
}

function imageStyle(own: string | null): string {
  return own ? `${own}; max-width: 100%` : "max-width: 100%";
}

Blockquotes and tables also get email-safe styles now.

Small images and a plain-text part

Two boring rules prevent a lot of trouble.

Images use one small variant. Every image in a Fotobank email is the 480 px watermarked small variant. On a stock photo site, an email is an easy place for an original to leak: emails get forwarded, and image URLs get copied out of them. The watermarked small variant is big enough to look good at email width and useless to anyone hoping for the full photo. The variants themselves come from the image pipeline I described in processing images with Sharp and S3.

Every email has a plain-text part. The message is sent as HTML plus a plain-text alternative. Some people read mail in text mode, and some clients show the text part in previews. Writing the text part is also a good check on the email itself: if it does not make sense without the design, the copy needs work.

Preview with the same function that sends

The admin screen has a live preview of the email as it is being written. That preview is rendered by the same function the queue uses to send, so the preview is exactly the sent email, with the email-safe pass applied. It shows the email at desktop and phone widths.

A preview built separately, say by dropping the editor's HTML into a div, will drift from what goes out. The styles bug above is the kind of thing a separate preview hides, because the editor output looks right in a browser. When preview and send share one function, there is one thing to check. It is the same idea as verifying a change by diffing old and new output: one code path, compared against what people really get.

One more lesson from the same pass: copy is part of the email. Fotobank's welcome email replaced an older plain email that wrongly told new buyers there was no password. People believe what an email tells them, so a wrong sentence there turns into support tickets.

Do styled email buttons work in Outlook?

Partly. Outlook's desktop versions on Windows ignore much of the CSS that makes a link look like a button, so a padded link can collapse to plain text. A button built from a table cell with a background colour holds up better, and a plain link under it covers every client that still drops it.

The short version

Style email addresses as your own mailto: links so Gmail does not restyle them. Put a plain link under every button. Let editor styles override your defaults, and put image max-width last. Use small watermarked images, always send a plain-text part, and preview with the function that sends. The same emails are part of the reminder flow in abandoned cart emails without double sends, and Fotobank is on my projects page.

Want this kind of work on your product?

Get in touch