HTML Formatted Email Not Showing Up at All in Gmail But Is in Other Mail Clients

HTML formatted email not showing up at all in Gmail but is in other mail clients

I am updating my answer since it has quite a few views, and new tools are available. I am leaving my original answer for posterity.

Edit * 9/19/19

You can find CSS property support by email client here:
https://www.caniemail.com/


Original Answer:

Gmail does not support the <style> tag. You need to use inline css for gmail to work correctly.

Here's a reference list.
http://www.campaignmonitor.com/css/

HTML email not received in gmail, but succeeds with yahoo, msn, aim, and work domain. Is it my HTML?

Some ideas:

  • Maybe GMail recognizes it as spam. Try some different content
  • Did you set the headers of the email correctly?
  • Did you specify a correct sender / sender name?

gmail does not render html in email

Edit #4

Here is another good version and seems easier to work with:

<?php
//define the receiver of the email
$to = 'email@example.com';
//define the subject of the email
$subject = 'Test HTML email';

// Generate a random boundary string
$mime_boundary = '_x'.sha1(time()).'x';

// Using the heredoc syntax to declare the headers
$headers = <<<HEADERS
From: Test <email@example.com>
MIME-Version: 1.0
Content-Type: multipart/alternative;
boundary="PHP-alt$mime_boundary"
HEADERS;

// Use our boundary string to create plain text and HTML versions
$message = <<<MESSAGE
--PHP-alt$mime_boundary
Content-Type: text/plain; charset="iso-8859-1"
Content-Transfer-Encoding: 7bit

This Is a Plain Text Email

This message has no HTML. http://www.google.com

--PHP-alt$mime_boundary
Content-type: text/html; charset=iso-8859-1
Content-Transfer-Encoding: 7bit

<html>
<body>
<h1>This Is an HTML Email</h1>
<p>
This message is composed in <a href="http://www.google.com">GOOGLE, click here</a>.
</p>
</body>
</html>
--PHP-alt$mime_boundary--
MESSAGE;

// Send the message
if(!mail($to, $subject, $message, $headers))
{
// If the mail function fails, return an error message
echo "Something went wrong!";
}
else
{
// Return a success message if nothing went wrong
echo "Message sent successfully. Check your email!";
}
?>


Edit 3

Another tested method: (which so far is the better method)

<?php

function send_email(

$to='email@example.com',
$from='email@example.com',
$subject='test',
$html_content='<b>HELLO in HTML bold</b>',
$text_content='Hi there in plain text',
$headers='')

{
# Setup mime boundary
$mime_boundary = 'Multipart_Boundary_x'.md5(time()).'x';

$headers = "MIME-Version: 1.0\r\n";
$headers .= "Content-Type: multipart/alternative; boundary=\"$mime_boundary\"\r\n";
$headers .= "Content-Transfer-Encoding: 7bit\r\n";

$body = "This is a multi-part message in mime format.\n\n";

# Add in plain text version
$body .= "--$mime_boundary\n";
$body .= "Content-Type: text/plain; charset=\"charset=us-ascii\"\n";
$body .= "Content-Transfer-Encoding: 7bit\n\n";
$body .= $text_content;
$body .= "\n\n";

# Add in HTML version
$body .= "--$mime_boundary\n";
$body .= "Content-Type: text/html; charset=\"UTF-8\"\n";
$body .= "Content-Transfer-Encoding: 7bit\n\n";
$body .= $html_content;
$body .= "\n\n";

# Attachments would go here
# But this whole email thing should be turned into a class to more logically handle attachments,
# this function is fine for just dealing with html and text content.

# End email
$body .= "--$mime_boundary--\n"; # <-- Notice trailing --, required to close email body for mime's

# Finish off headers
$headers .= "From: $from\r\n";
$headers .= "X-Sender-IP: $_SERVER[SERVER_ADDR]\r\n";
$headers .= 'Date: '.date('n/d/Y g:i A')."\r\n";

# Mail it out
return mail($to, $subject, $body, $headers);
}
send_email(); // call the function
?>


Edit 2

This worked, and only showed me in HTML in Gmail, so plain text should theoretically work.

<?php

$notice_text = "This is a multi-part message in MIME format.";
$plain_text = "This is a plain text email.\r\nIt is very cool.";
$html_text = "<html><body>This is an <b style='color:purple'>HTML</b>" .
"text email.\r\nIt is very cool.</body></html>";

$semi_rand = md5(time());
$mime_boundary = "==MULTIPART_BOUNDARY_$semi_rand";
$mime_boundary_header = chr(34) . $mime_boundary . chr(34);

$to = "Me <email@example.com>";
// $bcc = "You <you@you.com>, Them <them@them.com>";
$from = "Him <another@example.com>";
$subject = "My Email";

$body = "$notice_text

--$mime_boundary
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

$plain_text

--$mime_boundary
Content-Type: text/html; charset=us-ascii
Content-Transfer-Encoding: 7bit

$html_text

--$mime_boundary--";

if (@mail($to, $subject, $body,
"From: " . $from . "\n" .
"bcc: " . $bcc . "\n" .
"MIME-Version: 1.0\n" .
"Content-Type: multipart/alternative;\n" .
" boundary=" . $mime_boundary_header))
echo "Email sent successfully.";
else
echo "Email NOT sent successfully!";

?>


Edit 1

Try this version: (tested with no additional codes anywhere)

<?php
$to = "someone@gmail.com";
$subject = "Test HTML E-mail";

$headers = "From: admin@yellowcas.com" . "\n" . "Reply-To: admin@yellowcas.com" . "\r\n";
$headers .= "MIME-Version: 1.0\r\n";

//unique boundary
$boundary = uniqid("HTMLDEMO");

//tell e-mail client this e-mail contains//alternate versions
$headers .= "Content-Type: multipart/mixed; boundary = $boundary\r\n\r\n";

//plain text version of message
$body = "--$boundary\r\n" .
"Content-Type: text/plain; charset=ISO-8859-1\r\n" .
"Content-Transfer-Encoding: base64\r\n\r\n";
$body .= chunk_split(base64_encode("

Hello, Tom!!!
This is simple text email message.

"));

//HTML version of message
$body .= "--$boundary\r\n" .
"Content-Type: text/html; charset=ISO-8859-1\r\n" .
"Content-Transfer-Encoding: base64\r\n\r\n";
$body .= chunk_split(base64_encode("

<!doctype html>
<head>
<title>Untitled Document</title>
</head>
<body>
<h2>Hello, Tom!</h2>
<p>This is something with <strong>HTML</strong> formatting.</p>
</body>
</html>

"));
ob_start();

?>

<?php
$message = ob_get_clean();
$mail_sent = mail( $to, $subject, $body, $headers );
echo $mail_sent ? "Mail sent" : "Mail failed";
?>

You need to use the following in your initial headers:

$headers .= 'Content-type: text/html; charset=iso-8859-1' . "\r\n";

below:

$headers .= "MIME-Version: 1.0" . "\n";

as per the manual on PHP.net

Tested (successfully sent to my Gmail in HTML and not as code)

<?php
$to = "someone@gmail.com";
$subject = "Test HTML E-mail";
$random_hash = md5(date("r", time()));
$mID = md5($to);
$headers = "From: admin@yellowcas.com" . "\n" . "Reply-To: admin@yellowcas.com" . "\n";
$headers .= "Errors-To: someone@yahoo.com" . "\n";
$headers .= "MIME-Version: 1.0" . "\n";
$headers .= 'Content-type: text/html; charset=iso-8859-1' . "\r\n";
$headers .= "Content-Type: multipart/alternative; boundary=". $random_hash ." ; Message-ID: <" . $mID . ">" . "\n";
ob_start();
?>

// rest of code below...

How is CSS in emails treated by different email clients and in different reading formats?

  1. You can check how display:none is supported across email clients on Can I email. (Disclaimer: I'm the maintainer of the site.)

Can I email… display:none<br rel=" />


  1. HTML and plain text are two separate versions of an email. It’s up to you to send both versions and make sure that the content is relevant. From what I see from a WooCommerce I have, with the Storefront theme, it is set up by default to only send a text/html. You can change this WooCommerce > Settings > Emails, select an email and change the "Email type" value to Multi-part. You can then see in your admin the file you need to edit for the plain text version in your theme.

  2. You can use screenshots testing tools like Litmus (the biggest, well-known tool in the community), Email on Acid (my personal favorite) or Testi.at (good to have if you have a low budget).

My HTML email looks good on desktop, and iOS Gmail, but not Android Gmail. How do I eliminate the weird whitespace in between td?

If I open your HTML in Chrome on desktop on macOS, and I zoom in or zoom out, I get the exact same rendering issue as in your screenshot. My guess is the problem is that the Gmail app on your phone is auto-scaling the email to fit the screen, thus giving a similar rendering than what we can see in desktop in Chrome.

My advice would be first to get rid of the giant table with colspan and rowspan and replace this with individual nested tables. You might also try to make more simple slices of images in order to help the auto-scaling. If you manage to make it right in Chrome at different zoom levels, it should be ok on your phone.



Related Topics



Leave a reply



Submit