outlookcharacterhtml-emailwhitespaceapple-mail

Email clients are putting single space characters in HTML emails


I am sending HTML emails using the PHP mail function and have found that email clients are inserting single space characters at regular intervals. This is inconvenient when part of the email is a url.

I devised a test script to illustrate this:

<?php

$message = '<html><body>';
$message .= '</body></html>';
$message .= '123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456<br>';
$message .= '123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456<br>';
$message .= '123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456<br>';
$message .= '123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456<br>';
$message .= '123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456<br>';
$message .= '123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456<br>';
$message .= '123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456<br>';
$message .= '123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456<br>';
$message .= '123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456<br>';
$message .= '123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456<br>';
$headers = 'From: sender@domain.com' . "\r\n" . 'MIME-Version: 1.0' . "\r\n" . 'Content-type: text/html; charset=utf-8' . "\r\n";
$subject = 'Inserting spaces into HTML';
mail('receiver@domain.com', $subject, $message, $headers);

?>


In Outlook and Apple Mail, but not MailHog, this is the result:

123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456 123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456 123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456 123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456 123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456 123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456 123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456 123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456 123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456 1234567890123456789012345678901234567890123456 78901234567890123456789012345678901234567890123456

Note where the above has wrapped where the space occurred.

I have tried this with more lines and found that if you count the characters in the tags and the spaces themselves, this occurs every 998 characters (I think).

The simple workaround is to pad the preceding HTML with formatting so that the space does not occur within the url.

Does anyone have any explanation?


Solution

  • RFC 5321 defines that lines in an email must be at most 1000 bytes (including the final CRLF (\r and \n):

    The maximum total length of a text line including the <CRLF> is 1000 octets

    Since line breaks in HTML are just white space anyway, I'd just keep my lines under the maximum.

    If you really need longer lines, you can use quoted-printable encoding and add a = as a soft line break at the end of the line (as per rule 5 in section 5.1 of RFC 1341). Note that quoted printable only allows 76 bytes per line.

    Rule #5 (Soft Line Breaks): The Quoted-Printable encoding REQUIRES that encoded lines be no more than 76 characters long. If longer lines are to be encoded with the Quoted-Printable encoding, 'soft' line breaks must be used. An equal sign as the last character on a encoded line indicates such a non-significant ('soft') line break in the encoded text.

    So this

    one=
    line
    

    would be rendered as

    one line