Пользователь
0,0
рейтинг
24 июня 2012 в 13:08

Разработка → Особенности обработки HTML-писем

CSS*
Здравствуйте, хабраюзеры!

Недавно довелось копаться с рассылкой писем в HTML-формате. Есть много статей, написанных на тему валидной вёрстки рассылок, однако здесь речь пойдёт не об этом. Известно, что у каждого почтовика есть свои особенности отображения HTML-письма. Меня заинтересовали эти особенности и различия в отображении письма на разных почтовиках.

Под исследование попали три моих почтовых ящика в службах mail.ru, yandex.ru и gmail.com. Был написан скрипт, который отправлял на них одно и то же письмо в html формате. С помощью него я прогнал несколько вариантов и сравнил результаты. Вот что получилось:

Тег body


Тело письма, отображаемого почтовиками, начинается с тега body. Оно и понятно — всё письмо содержится именно в нём. Однако сам тег body может содержать атрибут style. В каждом почтовике тело письма представляется div'ом, однако не все переносят в этот div содержимое style.
  • Mail.ru — Тег body заменяется на <div id='style_id_BODY'>, где id — идентификатор пользователя, передаваемый в строке GET запроса. Атрибут style теряется. Кроме того, теряются любые другие атрибуты, задаваемые для тега body.
  • Yandex.ru — Тег body меняется на <div class='b-message-body__content'>. Стили не переносятся, как и любые другие атрибуты тега body.
  • Gmail.com — Тег body меняется на обычный div, стили переносятся. Кроме того, в этот div попадают атрибуты, установленные для body (имеются ввиду атрибуты типа background).


Особенности переноса атрибута style


Атрибут style зачастую анализируется почтовой машиной и может быть изменён перед отправкой пользователю. Как это происходит на исследуемых почтовиках:
  • Mail.ru — Обработка атрибута style производится по принципу «всё разрешено, что явно не запрещено». Пока удалось обнаружить, что под запрет попадает position: absolute.
  • Yandex.ru — Атрибуты style проходят предварительную обработку. Незнакомые стили (ну и соответственно, ошибки) не пропускаются. Обрезание стилей происходит таким образом, что в письмо, отображаемое клиенту попадают все стили до первого неизвестного. Таким образом, конструкция width:100px;some-new-style:new;background-color:#CCC; будет заменена на width:100px;
  • Gmail.com — Атрибуты style также проходят предварительную обработку, однако в этом случае требования более жёсткие, чем у Yandex.ru. Если в значении атрибута будет найден хотя бы один недопустимый стиль, весь атрибут игнорируется.


Отрицательные значения


Во всех статьях по вёрстке HTML-рассылок неоднократно упоминается, что про отрицательные значения (например в margin) можно забыть. Результат тестов вполне ожидаемый:
  • Mail.rumargin-left:-100px; — работает.
  • Yandex.rumargin-left:-100px; — не работает.
  • Gmail.commargin-left:-100px; -не работает.

Атрибут margin в Mail.ru пропускается только благодаря тому, что стили там не проходят предварительной обработки.

Поддержка CSS3


CSS 3 на данный момент находится в разработке, и некоторые почтовики считают определённые атрибуты недопустимыми. Итак, протестируем на наших трёх клиентах некоторые правила CSS3:

Mail.ru


Полная поддержка CSS3 и любых других браузерно-зависимых атрибутов ввиду очень лояльной фильтрации тега style.

Yandex.ru


  • linear-gradient — да
  • box-shadow — нет
  • border-radius — да
  • text-shadow — нет
  • word-wrap — нет
  • resize — нет
  • несколько background'ов — да
  • border-image -да

Gmail.com


  • linear-gradient — нет
  • box-shadow — нет
  • border-radius — да
  • text-shadow — да
  • word-wrap — да
  • resize — нет
  • несколько background'ов — да
  • border-image -нет


CSS height


Атрибут height поддерживается не всеми почтовиками.
  • Mail.ru — поддерживается.
  • Yandex.ru — поддерживается.
  • Gmail.com — не поддерживается, заменяется на min-height.


UPD: В комментариях выяснилось, что уловки типа javascript:*** и expression:*** блокируются системой безопасности mail.ru.
Артём @artyom_256
карма
11,0
рейтинг 0,0
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Спецпроект

Самое читаемое Разработка

Комментарии (19)

  • +1
    Нет почты на mail.ru, по этому не могу проверить. Что будет если

    <b style="display:block;position:absolute;left:0;top:0;width:100%;height:100%;background-color:red;font-size:36px;">Отправьте SMS на короткий номер...</b>
    

    Ведь все стили проходят, если я правильно понял?
    • 0
      Пока удалось обнаружить, что под запрет попадает position: absolute.
      • +2
        Это было добавлено уже после, см. обсуждение ниже ↓
  • +2
    Вот результат:
    <b style="display:block;;width:100%;height:100%;background-color:red;font-size:36px;" id="mailru-webagent-gen-43">Отправьте SMS на короткий номер...</b>
    Да, positon: absolute, и всё что с ним связано не пропускает.
    • 0
      В таком случае поправьте топик — фильтрация стилей в mail.ru все-таки есть.
      • 0
        Поправил.
    • 0
      Mail.ru обрабатывает теги по принципу «всё разрешено, что явно не запрещено».
      Yandex.ru и Gamil.com — по принцпу «всё запрещено, что явно не разрешено».

      Пробовал подставлять несуществующие правила css, mail.ru их пропускает.
  • 0
    Gmail.com — Тег body меняется на обычный div, стили переносятся. Кроме того, в этот div попадают атрибуты, установленные для body (имеются ввиду атрибуты типа background).
    По-моему, background как раз не проходит. Видимо, это связано с тем, что на GMail могут быть темы, и письмо будет показано на полупрозрачном белом фоне, который не так просто сделать белым, если у вас например джипеги с белым фоном (а png-файлы будут неприлично большими). Поэкспериментируйте сами, установив тему оформления на ящике GMail.
    • 0
      <div background="http://***/templates/default/images/background.png" style="min-height:100px;background-color:#e1e1e4;background:url('http://***/templates/default/images/background.png') 50% 50% fixed no-repeat;color:#fff;font-family:Calibri;font-size:14px;line-height:1.22">

      Это со страницы письма. Тема у меня стоит.
      • 0
        И работает правильно?

        P.S. Не знаю, какая у вас картинка, но белый текст на светло-сером фоне как-то не очень.
  • 0
    У кого есть IE6 и почта на mail.ru пробуем еще так:

    <b style="background-image:url(javascript:alert('HabraHabr'))">Ха-ха-ха!</b>
    

    Или так: (должно работать и в IE7)

    <b style="width:expression(alert('HabraHabr'));">Ха-ха!!!</b>
    
    • 0
      В IETester, режим IE6, под письмом:

      ВНИМАНИЕ!
      Данное письмо содержит потенциально опасный HTML-код, заблокированный системой безопасности.
      Возможно, оно отображается неправильно.
      • 0
        javascript:*** не пропускает система безопасности.
        • +4
          OK, пробуем так:

          <b style="background-image:url(&#1;JaVaScRiPt:AlErT('Habr'))">qwerty</b>
          

          Или так:

          <b style="background-image:\0075\0072\006C\0028'\006a\0061\0076\0061\0073\0063\0072\0069\0070\0074\003a\0061\006c\0065\0072\0074\0028.1027\0058.1053\0053\0027\0029'\0029">test</b>
          

          Прошу прощения, что засоряю комментарии к топику.
        • 0
          Выложите скрипт, давайте пошерстим интересные варианты, ибо особенность mail.ru не может не радовать с точки зрения возможных косяков.
          • 0
            Скрипт простейший. Я использую PHPMailer, просто отправляю через него письмо. Что-то вроде этого:

            $users = array(...); foreach($emails as $email) { try{ $mail = new PHPMailer(true); $mail->AddAddress($email); $mail->SetFrom('me@me.org', 'I am'); $mail->Subject = $title; $mail->MsgHTML(file_get_contents('mail.html')); $mail->CharSet = 'utf-8'; $mail->IsHTML(true); $mail->Send(); }catch(Exception $e){} }
            • 0
              Извиняюсь)

              $users = array(...);

              foreach($emails as $email)
              {
              try{
              $mail = new PHPMailer(true);
              $mail->AddAddress($email);
              $mail->SetFrom('me@me.org', 'I am');
              $mail->Subject = $title;
              $mail->MsgHTML(file_get_contents('mail.html'));
              $mail->CharSet = 'utf-8';
              $mail->IsHTML(true);
              $mail->Send();
              }catch(Exception $e){}
              }
        • +4
          Ах да, чуть не забыл! vbscript же есть :-)

          Не уверен, что будет работать, но попробовать стоит:

          <b style="background-image:url(vbscript:msgbox('HabraHabr'))">Ха-ха-ха!</b>
          
  • +1
    В Mail.ru вырезаются тег <style>, атрибут class и атрибуты событий (onclick, onload и т.д.). Из атрибута style вырезаются все правила, связанные с позиционированием. К тому же у блока, в котором отображается тело письма, применено свойство overflow, поэтому «выйти» за пределы контейнера и перекрыть элементы интерфейся вряд ли получится.
    image

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.