react-email icon indicating copy to clipboard operation
react-email copied to clipboard

Some email clients don't display background color on <Body> (including Outlook, and others)

Open magoz opened this issue 2 years ago • 14 comments

Describe the Bug

The README of the<Body> component states that you can use it to set the email background color and that is supported by the most popular email clients.

But Outlook, and other clients, ignore the background color set on the <Body>.

I've realized that the <Body> component is not listed in React Email docs but is used by all the examples.

Is this a known issue? If so, how should we go around it?

Screenshot 2023-04-25 at 20 29 21 Screenshot 2023-04-25 at 19 37 58 Screenshot 2023-04-25 at 19 37 48 Screenshot 2023-04-25 at 19 38 15 Screenshot 2023-04-25 at 19 38 27

Which package is affected (leave empty if unsure)

No response

Link to the code that reproduces this issue

https://demo.react.email/preview/codepen-challengers

To Reproduce

Send an email from the demo to an Outlook email address.

The email will not display the background color.

Expected Behavior

The background color set on <Body> is displayed by all email clients.

What's your node version? (if relevant)

No response

magoz avatar Apr 25 '23 18:04 magoz

For now we're using our own component for this which works great for us.

import { Body } from "@react-email/components";

export type EmailBodyHackProps = {
  children?: React.ReactNode;
  style?: React.CSSProperties;
};

export const EmailBodyHack = ({ children, style }: EmailBodyHackProps) => {
  return (
    <Body>
      <table width="100%" style={style}>
        <tbody>
          <tr style={{ width: "100%" }}>
            <td>{children}</td>
          </tr>
        </tbody>
      </table>
    </Body>
  );
};

Tested in outlook.com but not native Outlook yet.

Note: Naming is hard 😅

edenstrom avatar Apr 26 '23 10:04 edenstrom

Perhaps <Body> should implement something like this internally? @bukinoshita

magoz avatar Apr 26 '23 18:04 magoz

Yes, let's get this fixed.

bukinoshita avatar May 05 '23 15:05 bukinoshita

For now we're using our own component for this which works great for us.

import { Body } from "@react-email/components";

export type EmailBodyHackProps = {
  children?: React.ReactNode;
  style?: React.CSSProperties;
};

export const EmailBodyHack = ({ children, style }: EmailBodyHackProps) => {
  return (
    <Body>
      <table width="100%" style={style}>
        <tbody>
          <tr style={{ width: "100%" }}>
            <td>{children}</td>
          </tr>
        </tbody>
      </table>
    </Body>
  );
};

Tested in outlook.com but not native Outlook yet.

Note: Naming is hard 😅

The Container code is fairly similar if not the same as the code you posted except it has a max-width which can be overridden: https://github.com/resendlabs/react-email/blob/main/packages/container/src/container.tsx

I tried similar using <Container> with max-width set to none. It works great on the Gmail browser client but not on Apple Mail or Gmail iOS app.

<Body style={main}>
    // Added this next line
    <Container style={{ backgroundColor: '#0F1217', width: '100%', maxWidth: 'none' }}> 
        <Container style={container}>
            {... the rest of template code}
        </Container>
    </Container>
</Body>

jinsley8 avatar May 05 '23 16:05 jinsley8

Confirming this bug on Outlook. Trying the hack by @edenstrom.

ZeldOcarina avatar Jul 14 '23 13:07 ZeldOcarina

No luck with the hack on Outlook.. :(

ZeldOcarina avatar Jul 14 '23 13:07 ZeldOcarina

Faced the same issue and none of the solutions above worked for me.

What I ended up doing is also applying the styles to the html body on a style tag inside the Head component:

<Head>
    <style>
      {`
        body {
          background-color: #F2F2F2;
          margin: auto;
          padding: 32px 24px;
          font-family: sans-serif;
        }
      `}
    </style>
</Head>

Full code diff

Previously (didn't work):

import React from "react";
import {
  Body,
  Container,
  Head,
  Html,
  Img,
  Preview,
  Tailwind,
  Text,
} from "@react-email/components";

import tailwind from "@tailwind-config";

interface Props {
  children: React.ReactNode;
  previewText?: string;
}

export default function TemplateBase({ previewText, children }: Props) {
  return (
    <Html lang="en">
      <Head />
      {previewText && <Preview>{previewText}</Preview>}
      <Tailwind config={tailwind}>
        <Body className="mx-auto my-auto bg-[#F2F2F2] px-6 py-8 font-sans">
           ...
        </Body>
      </Tailwind>
    </Html>
  );
}

Currently (works):

import React from "react";
import {
  Body,
  Container,
  Head,
  Html,
  Img,
  Preview,
  Tailwind,
  Text,
} from "@react-email/components";

import tailwind from "@tailwind-config";

interface Props {
  children: React.ReactNode;
  previewText?: string;
}

export default function TemplateBase({ previewText, children }: Props) {
  return (
    <Html lang="en">
      <Head>
        <style>
          {`
            body {
              background-color: #F2F2F2;
              margin: auto;
              padding: 32px 24px;
              font-family: sans-serif;
            }
          `}
        </style>
      </Head>
      {previewText && <Preview>{previewText}</Preview>}
      <Tailwind config={tailwind}>
        <Body>
          ...
        </Body>
      </Tailwind>
    </Html>
  );
}

I had to keep both the style tag and the inline styles becase on gmail it works only with the inline styles and on outlook only with the style tag.

I tested it in both Gmail and Outlook and, although I believe does not make a difference, using both resend and AWS SES with the render method. Every combination worked

rbestardpino avatar Oct 02 '23 00:10 rbestardpino

Thanks @rbestardpino. I feel this is still an issue though as the purpose of the framework is to normalize HTML quirks between browsers etc. and needing to go through hacks to style the background is sub-optimal imo

ZeldOcarina avatar Oct 02 '23 06:10 ZeldOcarina

@ZeldOcarina There are limitations to some email clients that just can't be changed but I agree it would be good to at least list those limitations in docs so users are aware.

Email preview testing software like Litmus and Email on Acid start at $99/mo so most user would not have the ability to check if their emails aren't rendering correctly.

Here are email previewer services to help test your designs across clients. I haven't tried the free ones yet so I don't know how accurate they are:

Free: https://putsmail.com/ https://inboxanalyzer.io/features https://emailpreview.io/

Paid: https://www.litmus.com/ https://www.emailonacid.com/ https://emailpreviewservices.com/en/features/email-design-testing https://mailosaur.com/email-testing https://www.sendforensics.com/features/client-previews/

jinsley8 avatar Oct 02 '23 13:10 jinsley8

Other libraries like Mailing and Maizzle use https://github.com/Automattic/juice to do the automatic conversion of CSS classes to inline styles. You should adopt this.

timothyjoh avatar Nov 20 '23 20:11 timothyjoh

Do we have a fix coming for this?

missbruni avatar Nov 21 '23 19:11 missbruni

Chiming in here, this is a nuisance. To get around both Outlook and Gmail, and to still not ruin it for other clients, I had to specify the CSS for the background twice, and remove it from the <Body> tag.

endymion1818 avatar Apr 02 '24 13:04 endymion1818

Any updates?

shahneil avatar Aug 04 '24 21:08 shahneil