uCheckeruChecker
·15 мин

Верстка адаптивных email-писем:
HTML, CSS и подводные камни

Email-рассылка выглядит отлично в браузере и разваливается в Outlook. Знакомая ситуация. Причина одна: email-клиенты рендерят HTML по собственным правилам, и эти правила далеки от веб-стандартов.

В этом руководстве - конкретный код: скелет письма, инлайн-стили, media queries, работа с картинками и тёмной темой. Каждый пример проверен в Gmail, Outlook 2019/365, Apple Mail и Яндекс.Почте.

Почему таблицы, а не div

Веб ушёл от табличной верстки пятнадцать лет назад. Email - нет. Outlook на Windows использует движок рендеринга Microsoft Word (да, тот самый Word) для отображения HTML. Word не понимает flexbox, grid и большую часть position. Зато он нормально рендерит таблицы.

Gmail вырезает тег <style> из <head>, если письмо превышает 102 КБ. Yahoo Mail обрезает CSS-анимации. Mail.ru игнорирует max-width на div-элементах, но корректно применяет его на ячейках таблицы.

Итог: таблицы - основа раскладки email-письма. Это не рекомендация, а необходимость.

Базовый скелет письма

Каждое email-письмо начинается с одной и той же структуры. Внешняя таблица - 100% ширины, задаёт фон. Внутренняя - фиксированная ширина содержимого, обычно 600px. Это значение не случайное: большинство десктопных клиентов отображают панель preview шириной 600-700px.

<!DOCTYPE html>
<html lang="ru" xmlns="http://www.w3.org/1999/xhtml">
<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  <title>Тема письма</title>
  <!--[if mso]>
  <style>
    table { border-collapse: collapse; }
    .fallback-font { font-family: Arial, sans-serif; }
  </style>
  <![endif]-->
</head>
<body style="margin:0; padding:0; background-color:#f4f4f4;">
  <!-- Внешняя обёртка -->
  <table role="presentation" width="100%" cellpadding="0"
         cellspacing="0" style="background-color:#f4f4f4;">
    <tr>
      <td align="center" style="padding: 20px 0;">
        <!-- Контейнер 600px -->
        <table role="presentation" width="600" cellpadding="0"
               cellspacing="0"
               style="background-color:#ffffff; max-width:600px;">
          <tr>
            <td style="padding: 40px 30px;">
              <!-- Контент письма -->
            </td>
          </tr>
        </table>
      </td>
    </tr>
  </table>
</body>
</html>

Обратите внимание на несколько деталей. Атрибут role="presentation" сообщает скринридерам, что таблица используется для раскладки, а не для данных. Условный комментарий <!--[if mso]> подключает стили только для Outlook на Windows. cellpadding="0" и cellspacing="0" обнуляют отступы по умолчанию, которые у каждого клиента свои.

Инлайн-стили: обязательный минимум

Gmail, Yahoo Mail и ряд других клиентов вырезают или игнорируют блок <style> в <head>. Единственный способ гарантировать стили - прописать их в атрибуте style каждого элемента. Это громоздко, но альтернатив нет.

<!-- Заголовок -->
<td style="padding: 0 0 20px 0;">
  <h1 style="margin: 0;
             font-family: Arial, Helvetica, sans-serif;
             font-size: 28px;
             line-height: 1.3;
             color: #1a1a1a;
             font-weight: bold;">
    Заголовок вашего письма
  </h1>
</td>

<!-- Параграф -->
<td style="padding: 0 0 16px 0;">
  <p style="margin: 0;
            font-family: Arial, Helvetica, sans-serif;
            font-size: 16px;
            line-height: 1.6;
            color: #4a4a4a;">
    Текст параграфа. Каждое свойство — inline.
  </p>
</td>

<!-- Кнопка (bulletproof) -->
<td style="padding: 20px 0;">
  <table role="presentation" cellpadding="0" cellspacing="0">
    <tr>
      <td style="background-color: #4c49fa;
                 border-radius: 6px;
                 text-align: center;">
        <a href="https://example.com"
           target="_blank"
           style="display: inline-block;
                  padding: 14px 32px;
                  font-family: Arial, Helvetica, sans-serif;
                  font-size: 16px;
                  font-weight: bold;
                  color: #ffffff;
                  text-decoration: none;">
          Перейти к действию
        </a>
      </td>
    </tr>
  </table>
</td>

Кнопка в примере выше - так называемая bulletproof button. Она не зависит от background-image (который часто блокируется) и сохраняет кликабельную область даже при отключённых картинках.

Совет: пишите стили руками только для прототипа. Для продакшена используйте CSS-инлайнер: juice (Node.js), premailer (Python/Ruby) или встроенный инструмент вашего ESP. Они возьмут обычный CSS из <style> и перенесут его в атрибуты style.

Адаптивность через media queries

Более 60% email-писем открывают на мобильных устройствах. Письмо шириной 600px на экране шириной 375px превращается в горизонтальный скролл, если не добавить адаптивность.

Поддержка media queries различается между клиентами. Apple Mail, iOS Mail, Samsung Mail - поддерживают полностью. Gmail app на Android - игнорирует <style> в <head>, но поддерживает инлайн media queries через <style> в <body>. Outlook на Windows - не поддерживает вовсе.

Рабочая стратегия: fluid layout в базе плюс media queries для клиентов, которые их понимают. Outlook получит фиксированную ширину через условный комментарий.

<style>
  /* Базовые адаптивные стили */
  @media only screen and (max-width: 620px) {
    .email-container {
      width: 100% !important;
      max-width: 100% !important;
    }
    .stack-column {
      display: block !important;
      width: 100% !important;
    }
    .stack-column-center {
      display: block !important;
      width: 100% !important;
      text-align: center !important;
    }
    .mobile-padding {
      padding-left: 20px !important;
      padding-right: 20px !important;
    }
    .mobile-hide {
      display: none !important;
    }
    .mobile-font-large {
      font-size: 22px !important;
      line-height: 1.3 !important;
    }
  }
</style>

<!-- Двухколоночная раскладка, которая схлопывается -->
<table role="presentation" width="100%" cellpadding="0"
       cellspacing="0">
  <tr>
    <td>
      <!--[if mso]>
      <table role="presentation" width="600" cellpadding="0"
             cellspacing="0" align="center">
      <tr>
      <td width="290" valign="top">
      <![endif]-->
      <div class="stack-column"
           style="display:inline-block; width:290px;
                  vertical-align:top;">
        <table role="presentation" width="100%">
          <tr>
            <td style="padding: 10px;">
              <!-- Левая колонка -->
            </td>
          </tr>
        </table>
      </div>
      <!--[if mso]>
      </td>
      <td width="290" valign="top">
      <![endif]-->
      <div class="stack-column"
           style="display:inline-block; width:290px;
                  vertical-align:top;">
        <table role="presentation" width="100%">
          <tr>
            <td style="padding: 10px;">
              <!-- Правая колонка -->
            </td>
          </tr>
        </table>
      </div>
      <!--[if mso]>
      </td>
      </tr>
      </table>
      <![endif]-->
    </td>
  </tr>
</table>

Ключевой приём: display: inline-block на div-обёртках колонок. На десктопе две колонки стоят рядом. На мобильных media query переключает их в display: block; width: 100%, и они выстраиваются друг под другом. А для Outlook условный комментарий создаёт жёсткую табличную структуру с фиксированными ширинами.

Картинки и ретина

Три правила для изображений в email. Первое: всегда указывайте атрибуты width и height. Без них Outlook растянет картинку до полной ширины контейнера. Второе: добавляйте alt - текст с описанием, потому что Gmail, Outlook и корпоративные клиенты по умолчанию блокируют картинки. Третье: для retina-экранов загружайте изображение в 2x-разрешении и задавайте отображаемый размер через атрибуты.

<!-- Адаптивная картинка для retina -->
<img src="https://cdn.example.com/hero-1200.png"
     alt="Описание изображения"
     width="600"
     height="300"
     style="display: block;
            width: 100%;
            max-width: 600px;
            height: auto;
            border: 0;
            outline: none;"
/>

<!-- Фоновая картинка с фолбэком для Outlook -->
<!--[if mso]>
<v:rect xmlns:v="urn:schemas-microsoft-com:vml"
        fill="true" stroke="false"
        style="width:600px; height:300px;">
  <v:fill type="frame"
          src="https://cdn.example.com/bg.png" />
  <v:textbox inset="0,0,0,0">
<![endif]-->
<div style="background-image: url('https://cdn.example.com/bg.png');
            background-size: cover;
            background-position: center;
            max-width: 600px;">
  <table role="presentation" width="100%">
    <tr>
      <td style="padding: 40px 30px; color: #ffffff;">
        <!-- Контент поверх фона -->
      </td>
    </tr>
  </table>
</div>
<!--[if mso]>
  </v:textbox>
</v:rect>
<![endif]-->

VML-разметка (Vector Markup Language) - единственный способ заставить фоновое изображение работать в Outlook на Windows. Без неё Outlook покажет белый фон вместо картинки. Выглядит архаично, но работает стабильно вплоть до Outlook 2021 и Microsoft 365.

Тёмная тема

Apple Mail, Outlook.com и Gmail (частично) инвертируют цвета писем, когда у пользователя включена тёмная тема ОС. Белый фон становится тёмно-серым, чёрный текст - светлым. Проблема в том, что инверсия применяется автоматически и не всегда корректно: тёмно-синий логотип на белом фоне превращается в невидимый тёмно-синий логотип на тёмно-сером фоне.

/* Стили для тёмной темы */
@media (prefers-color-scheme: dark) {
  .email-body {
    background-color: #1a1a2e !important;
  }
  .email-container {
    background-color: #16213e !important;
  }
  .text-primary {
    color: #e0e0e0 !important;
  }
  .text-secondary {
    color: #b0b0b0 !important;
  }
}

/* Мета-тег для Apple Mail */
:root {
  color-scheme: light dark;
  supported-color-schemes: light dark;
}

Мета-тег color-scheme говорит Apple Mail: «это письмо готово к тёмной теме, не инвертируй цвета автоматически - я задам их сам». Без этого мета-тега Apple Mail применит собственную инверсию, которая может исказить дизайн.

Практический совет: добавляйте прозрачный контур (stroke) вокруг тёмных логотипов - 2-3px белой или светлой обводки. Так логотип останется читаемым на любом фоне. Либо подготовьте две версии логотипа и переключайте их через media query.

Совместимость с email-клиентами

Разные клиенты поддерживают разный набор CSS-свойств. Вот таблица ключевых различий, которую стоит держать под рукой.

СвойствоGmailOutlookApple MailЯндекс
media queriesЧастичноНетДаДа
flexbox / gridНетНетДаНет
background-imageДаVMLДаДа
border-radiusДаНетДаДа
marginЧастичноЧастичноДаДа
<style> в <head>До 102 КБДаДаДа
SVGНетНетДаНет

Из таблицы видно: единственный клиент с полной поддержкой современного CSS - Apple Mail. Все остальные требуют компромиссов. Стратегия progressive enhancement работает: делаете базовую версию на таблицах с инлайн-стилями, затем добавляете улучшения через <style> для клиентов, которые их поддерживают.

Outlook и Word-движок. Outlook 2007, 2010, 2013, 2016, 2019 и Microsoft 365 на Windows используют Word для рендеринга HTML. Outlook на macOS использует WebKit - и ведёт себя как Safari. Outlook.com (веб) - отдельная история со своими ограничениями. Не путайте их: это три разных движка под одним брендом.

Тестирование перед отправкой

Сверстать письмо - половина работы. Вторая половина - убедиться, что оно выглядит корректно в десятках клиентов. Ручная проверка в каждом клиенте нереальна, поэтому используют инструменты.

Litmus и Email on Acid делают скриншоты вашего письма в 90+ клиентах. Стоят от $80/мес, но для команд, которые отправляют регулярно, - окупаются. Бесплатная альтернатива - PutsMail (от Litmus): отправляет тестовое письмо на ваш ящик, без скриншотов, но достаточно, чтобы проверить Gmail и Outlook вручную.

Минимальный набор для ручного тестирования:

Не забудьте про валидацию базы. Идеально свёрстанное письмо бесполезно, если оно улетает на несуществующие адреса. Проверка списка получателей перед отправкой убирает hard bounces и защищает репутацию домена.

Чек-лист перед отправкой

Вот список того, что стоит проверить перед каждой рассылкой. Распечатайте или сохраните в закладки.

1

Раскладка построена на таблицах, а не на div/flexbox/grid

2

Все стили продублированы в inline-атрибуте style

3

Указаны width и height у каждого img, добавлен alt-текст

4

Картинки загружены в 2x для retina, формат PNG или JPEG

5

Кнопки сверстаны как bulletproof (таблица + ссылка)

6

Есть fallback для тёмной темы (color-scheme мета-тег)

7

Добавлены условные комментарии для Outlook (<!--[if mso]>)

8

Размер HTML не превышает 102 КБ (лимит Gmail)

9

Протестировано в Gmail, Outlook, Apple Mail, Яндекс

10

Есть plain-text версия письма

11

База получателей провалидирована

Письмо свёрстано. А база проверена?

Загрузите список email-адресов в uChecker - мы покажем, какие из них невалидны, какие ведут на спам-ловушки и какие давно заброшены. Результаты за минуты.

Проверить базу в uChecker
вёрстка email HTMLадаптивный email шаблонHTML email CSSemail-клиенты совместимостьresponsive email design