Меню

Урок 8. Мобильная адаптация

Чтобы получать письма от любимых брендов, нужно сперва подписаться на рассылки любимых брендов. А где мы их читаем? В основном, на экране компьютера или ноутбука. Вот только на дворе XXI век: мы мобильны и помимо ноутбуков имеем смартфоны и планшеты. 

По данным Statista, 92,6% пользователей интернета заходит в сеть через мобильные устройства. Именно поэтому корректное отображение письма на разных девайсах — это сразу +50 баллов к успешности рассылки. Об этом и поговорим. 

По сути, мы уже затронули адаптацию в предыдущем уроке, когда изучали перестраивающиеся блоки — теперь расскажем о других элементах. Но сперва давайте поймём, какие бывают экраны.  

Адаптивность и размеры экранов

Адаптивностью в имейл‑маркетинге называют возможность письма подстраиваться под ширину экрана. Да так, чтобы текст был читабельным, а картинки — оптимального размера. 

Такой подход к вёрстке ещё называют резиновым. Его суть в том, что верстальщик указывает размер каждого блока не в пикселях, а в процентах. В результате резиновая вёрстка подстраивается под разные экраны, и всем удобно читать. 

Вот пример, как может выглядеть одна и та же веб‑страница на разных устройствах:

Здесь стоит отметить, что в вёрстке мы ориентируемся именно на разрешение экрана, а не на его размер. Размер экрана — это длина его диагонали в дюймах, а разрешение дисплея показывает количество пикселей на экране. Кстати, устройства с одинаковыми размерами экранов могут иметь разные разрешения.

Минимальная ширина мобильных устройств — 320px. Значит, вёрстка письма должна корректно отображаться в диапазоне от 320px до 620px.

Адаптация изображений

Начнём с картинок, и для примера возьмём баннер шириной 600px:

Код вы уже знаете:

<span style=»font-family: Tahoma, Arial, Helvetica, sans-serif; font-size: 16px;color:#000000;»>

<img src=»creative-main.png» width=»600″ height=»500″ alt=»Альтернативный текст» border=»0″ style=»display: block; />

   </span>

Здесь всё стандартно: ссылка на баннер, стили альтернативного текста, ширина и высота изображения. Вот только при сужении экрана такой код сломает всю остальную вёрстку — элементы письма просто уменьшатся до ширины 320px, станут мелкими и нечитабельными.  

Поэтому существует правило: для всех изображений шириной больше 300px не нужно прописывать фиксированную высоту. Когда высота не прописана в коде, система самостоятельно её вычислит пропорционально размеру картинки. 

Чтобы картинка шириной больше 300px начала адаптироваться и не ломала вёрстку, в стилях прописываем ширину в процентном соотношении [100%], и максимальную ширину картинки [600px], используя резиновый подход:

<span style=»font-family: Tahoma, Arial, Helvetica, sans-serif; font-size: 16px;color:#000000;»>

<img src=»creative-main.png» width=»600″ alt=»Альтернативный текст» border=»0″ style=»display: block; width: 100%; max-width: 600px» />

   </span>

Десктопные версии [в том числе Outlook] увидят запись width=»600″ и покажут баннер шириной 600px. Google прочитает запись width: 100%; max-width: 600px и отобразит изображение на всю ширину, но не более 600px.

Таким образом у нас получилось масштабирование изображения, которое не помешает адаптироваться всему остальному контенту письма. 

Есть один нюанс с GIF-изображениями: вообще, они работают также, как и обычные PNG-картинки, но если Outlook 2019 не увидит заданную высоту гифки, он сломает всю вёрстку. Чтобы этого не случилось, для анимации прописываем height и задаём значение auto в стилях:

<span style=»font-family: Tahoma, Arial, Helvetica, sans-serif; font-size: 16px;color:#000000;»>

   <img src=»main.gif» width=»600″ height=»500″ alt=»Альтернативный текст» border=»0″ style=»display: block; width: 100%; max-width: 600px; height: auto» />

</span>
Теперь Outlook 2019 увидит запись width=»600″ height=»500″ и ничего не поломает, остальные же почтовики прочитают height: auto, которая «перекрывает» предыдущую.

Масштабирование кнопок

Кнопки в письмах бывают разные: 

Бывает даже, что их растягивают на всю ширину экрана:

А вот как будет масштабироваться такая кнопка:

<table width=»100%» border=»0″ cellspacing=»0″ cellpadding=»0″ style=»width: 100%;»>

   <tr><td align=»center» valign=»middle» height=»50″ bgcolor=»#000″ style=»height: 50px; display: block; background-color: #000000;»>

       <!—[if gte mso 9]>

       <table border=»0″ cellspacing=»0″ cellpadding=»0″>

       <tr><td nowrap align=»center» valign=»middle» height=»50″ style=»padding: 0 30px;»>

       <![endif]—>

       <a href=»#» target=»_blank» style=»font-family: Arial, Helvetica, sans-serif; font-size: 24px; line-height: 50px; color: #ffffff; white-space: nowrap; font-weight: normal; text-decoration: none; display: block; padding: 0 30px;»>

           Текст кнопки

       </a>

       <!—[if gte mso 9]>

       </td></tr>

       </table>

       <![endif]—>

   </td></tr>

   </table>

Важно, чтобы высота строки соответствовала высоте кнопки, а её текст был меньше 300px в ширину. Если будет больше — текст либо сломает адаптацию, упёршись в края кнопки при сужении [при наличии свойства white-space со значением nowrap], либо неминуемо перестроится и вылезет за пределы кнопки.

Адаптация текста

Бывает, что на этапе дизайна специалист придумал заголовок в письме большого размера:

<div style=»line-height: 56px;»>

   <span style=»font-family: Arial, Tahoma, Helvetica, sans-serif; font-size: 54px; color:#000000;font-weight: bold;»>

       Заголовок

   </span>

   </div>

В таких случаях текст при сужении экрана упрётся в свой размер, и вёрстка поедет. Чтобы это исправить: а) лучше не использовать длинные и крупные заголовки; б) можно использовать медиа‑запросы.

Идём в медиа‑запросы, придумываем название класса [например, fs38] и прописываем высоту текста и строки, которые увидят подписчики на мобильном устройстве [например, 38px и 40px]. Не забываем добавить объявление !important, чтобы задать приоритетность. 

Теперь наши медиа‑запросы выглядят так:

@media only screen and (max-device-width: 620px), only screen and (max-width: 620px) {

   .mob_100{

       width:100% !important;

   }

   .mob_300 {

       width: 300px !important;

   }

   .mob_center{

       text-align: center !important;

   }

   .mob_center_bl{

       float:none !important;

       display: block !important;

       margin: 0 auto;

   }

   .mob_hidden{

       display:none !important;

   }

   .mob_no_border{

       border-right-width: 0px !important;

   }

   .fs38 {

      font-size: 38px !important;

      line-height: 40px !important;

   }

}

Пока медиа‑запрос не работает — мы лишь его описали в CSS. Поэтому задаём класс в теге <span>: 

<div style=»line-height: 40px;»>

   <span class=»fs38″ style=»font-family: Arial, Tahoma, Helvetica, sans-serif; font-size: 38px; color:#000000;font-weight: bold;»>

       Заголовок

   </span>

   </div>

Теперь при сужении экрана заголовок обретёт размер 38px. Но не везде — Яндекс не видит медиа‑запросы. Поэтому лучше всё же не использовать длинные и настолько крупные заголовки 🙂 

Медиа‑запросы

Теперь давайте остановимся на медиа‑запросах подробнее. Итак, вот наша встроенная таблица стилей для включения медиа‑запросов:

<style type=»text/css»>

html { -webkit-text-size-adjust:none; -ms-text-size-adjust: none;}

@media only screen and (max-device-width: 620px), only screen and (max-width: 620px) { 

.mob_100{

width:100% !important;

}

.mob_center{

text-align: center !important;

}

.mob_center_bl{

float:none !important;

display: block !important;

margin: 0 auto;

}

.mob_hidden{

display:none !important;

}

    .mob_no_border{

border-right-width: 0px !important;

}

}

.mob_link a{

text-decoration:none;

color:#b1bac3;

}

.preheader{

display:none !important;

}

</style>

Первое имя класса .mob_100 задаёт ширину контейнера — в данном случае это 100%. Давайте посмотрим на примере двух одинаковых перестраивающихся блоков:

<table width=»100%» border=»0″ cellspacing=»0″ cellpadding=»0″>

   <tr><td align=»center» valign=»top» style=»font-size: 0px;»><!—

   Item —><div style=»display: inline-block;vertical-align:top;max-width:300px;width=100%»>

       <table width=»100%» border=»0″ cellspacing=»0″ cellpadding=»0″ style=»border-collapse:collapse;»>

           <tr><td align=»center» valign=»middle» style=»font-size: 14px;»>

               <table width=»100%» border=»0″ cellspacing=»0″ cellpadding=»0″ >

                   <tr><td align=»center» valign=»top»>

                       Съешь ещё этих мягких французских булок, да выпей чаю.

                   </td></tr>

               </table>

           </td></tr>

       </table></div><!— Item END—><!—[if (gte mso 9)|(IE)]>

       </td>

       <td valign=»top» style=»width: 200px;»>

   <![endif]—><!—

   Item —><div class=»mob_100″ style=»display: inline-block;vertical-align:top; width:300px»>

       <table width=»100%» border=»0″ cellspacing=»0″ cellpadding=»0″ style=»border-collapse:collapse;»>

           <tr><td align=»center» valign=»middle» style=»font-size: 14px;»>

               <table width=»100%» border=»0″ cellspacing=»0″ cellpadding=»0″ >

                   <tr><td align=»center» valign=»top»>

                       Съешь ещё этих мягких французских булок, да выпей чаю.

                   </td></tr>

               </table>

           </td></tr>

       </table></div><!— Item END—>

   </td></tr>

   </table>

На широком экране этот код будет отображаться так: 

Съешь ещё этих мягких французских булок, да выпей чаю. Съешь ещё этих мягких французских булок, да выпей чаю. 

Мы задали класс только второму блоку, поэтому при сужении экрана и перестроении контента отобразится так:

Съешь ещё этих мягких французских булок, да выпей чаю. 
Съешь ещё этих мягких французских булок, да выпей чаю. 

Почти таким же образом можно растянуть на всю ширину экрана изображение. Вот код:

<div class=»mob_100″ style=»dislay:inline-block; vertical-align:top; width:300px; «>

  <table width=»100%» border=»0″ cellspacing=»0″ cellpadding=»0″ style=»border-collapse:collapse;»>

      <tr><td align=»center» valign=»middle» style=»font-size: 14px;»>

        <table width=»100%» border=»0″ cellspacing=»0″ cellpadding=»0″

          <tr><td align=»center» valign=»top»>

       <a href=»#» style=»font-family: Tahoma, Arial, Helvetica, sans-serif; font-size: 16px;color:#000000;»>

       <img class=»mob_100″ src=»img.png» width=»300″ alt=»текст» border=»0″ style=»display: block;width:100%; height: auto;» />

       </a>

          </td></tr>

        </table>

      </td></tr>

  </table></div>

Как видите, здесь задана ширина картинки [width=»300″]. Чтобы растянуть её на всю ширину экрана, нужно задать признаки масштабируемой картинки с помощью значения width:100% в теге <style>. Значение же auto устанавливает высоту картинки относительно ширины. Не забудьте добавить класс mob_100 везде, где контент должен расширяться. 

Следующий класс mob_center после перестроения выравнивает текст по центру. Код будет такой: 

 <div class=»mob_center» style=»line-height: 14px;»>

   <span style=»font-family: Arial, Tahoma, Helvetica, sans-serif; font-size: 12px; color:#000000;»>

      Этот текст окажется по центру после перестроения.

   </span>

</div>

Здесь может возникнуть вопрос: а почему, собственно, мы присвоили класс mob_center тегу <div>, а не <span>? Объясняем: свойство text-align в медиа‑запросах применимо только для блочных элементов, а <span> — это строчный элемент.

Аналогично работает класс mob_center_bl, только уже не с текстом, а с блоком [например, с картинкой]. Свойство float определяет, по какой стороне будет выравниваться элемент. При этом остальные элементы будут обтекать его с других сторон, пока ему не зададут значение none — таким образом мы выключаем обтекание элемента. 

Строка margin: 0 auto устанавливает внешний отступ элемента. Это свойство может задать величину отступа сразу для всех сторон — можно использовать до четырёх значений, разделяя их между собой пробелом [например, margin: 0 0 0 0]. В нашем случае мы используем два значения: 0 и auto. Первое устанавливает нулевой отступ от верхнего и нижнего края, второе автоматически рассчитывает размер отступа от левого и правого края.

Медиа‑запрос mob_hidden при перестроении полностью скрывает блок, а mob_no_border скрывает границы элемента. После этого фигурная скобка закрывает медиа‑запросы. 

На CSS-классах mob_link и preheader мы подробно останавливались в третьем уроке, но на всякий случай напомним: первый убирает оформление текста [например, подчёркивание ссылок в Google], а второй скрывает прехедер. 

Так, мы рассмотрели основные медиа‑запросы, которые могут часто встречаться. Другие правила можно придумать и комбинировать между собой так, как душе угодно 🙂

Тёмная тема

Тёмный режим, или Dark Mode, появился в 2019 году. С тех пор разработчики внедряют такой пользовательский интерфейс во многие программы и мобильные приложения. И почтовики, конечно. 

Как это работает? Всё просто: при включении Dark Mode фон страницы становится тёмным, а шрифт — светлым. Некоторые почтовики делают прямую инверсию «белый — чёрный», а некоторые «подбирают» тёмный аналог. Так, например, если фон верстается картинкой, происходит инверсия цвета текста, что может повлиять на его читабельность. Важно, что разные сервисы по‑разному работают с тёмной темой и результат будет отличаться. 

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

Единственное решение этой проблемы — добавить прозрачности на этапе дизайна. Отдельный макет для тёмной темы делать не нужно, но дизайнер может себя проверить: создать затемнённый блок и посмотреть, как на него ляжет баннер в тёмной теме.

Ещё лучше — сделать фон таким цветом, на котором будет хорошо читаться как белый текст, так и чёрный:

Важно помнить: если фон будет верстаться кодом, его цвет тоже будет инвертироваться. Однако какие‑то градиенты нужно верстать картинкой: прямой градиент из двух цветов легко сверстать кодом, но если он более сложный — уже не получится. 

Чёрно‑белые или серые иконки, которые используются в дизайне письма, должны быть с обводкой в цвет фона [1–1,5 px]. В светлой теме её не будет видно, зато в тёмной — ещё как. Это же правило относится к нестандартным шрифтам, которые используются в заголовках.

Если кнопку верстать кодом, она тоже будет инвертироваться. Когда в светлой теме у кнопки есть обводка, этого можно избежать: верстать кнопки картинками, добавляя заливку в цвет фона. В светлой теме это будет выглядеть как обводка, а в тёмной — как обычная кнопка.

Ещё один вариант для дизайна кнопки — добавить обводку или свечение. Их не будет видно на светлой теме, зато в тёмной благодаря этому нужный элемент никуда не потеряется. Главное — найти баланс, чтобы везде был одинаковый контраст.

А вот картинки, в том числе GIF-изображения, в тёмной теме никак не поменяются. Цвета останутся те же, однако если у гифки верхним слоем будет верстаться кнопка или текст — они как раз будут адаптироваться под новые реалии тёмной темы. Избежать этого можно двумя способами: верстать кнопку и текст картинкой, или сделать фоновую гифку таким цветом, чтобы другие элементы были контрастными на её фоне.

Тени в тёмной теме выглядят как свечение, поэтому у них стоит выкрутить прозрачность примерно на 25% — можно больше, можно меньше. А тени у GIF-изображений — вообще отдельная история, они очень криво сохраняются и иногда вообще не отображаются, потому что GIF-формат не поддерживает полупрозрачность. Поэтому в анимации лучше вообще не использовать тени на прозрачном фоне.

Меню разработчика

Поможет проверить вёрстку, и заодно — себя. Когда письмо собрано, его можно открыть прямо в браузере и проверить отображение кода с помощью инструментов разработчика.

Как это сделать: кликаете по HTML-файлу правой кнопкой мыши и открываете его через браузер. В большинстве браузеров под Windows панель разработчика можно открыть с помощью клавиши F12, в Chrome под Mac поможет комбинация Cmd+Opt+J, а в Safari — Cmd+Opt+C [но предварительно нужно включить «Меню разработчика» в настройках]. Вот как это выглядит:

В верхней панели выбираете модель устройства или самостоятельно задаёте размеры экрана:

Выбрав пункт «Отзывчивое устройство», можно сужать и расширять письмо, как вам захочется: 

Здесь можно работать параллельно с редактором кода: для этого нужно открыть тот же HTML-файл в редакторе, внести изменения и сохранить. Тогда после обновления страницы браузера письмо отобразится с вашими правками. В основном работа верстальщика концентрируется на Elements [Элементы] — там отображается дерево HTML, которое помогает при вёрстке.

Подробнее о том, как работать с инструментами разработчика, можно почитать в справке браузера — вот, например, инструкция от Google.

Итак, позади 8 уроков по вёрстке писем, а впереди — финишная прямая! Вы уже без труда можете собрать рассылку, но это лишь 50% её успеха. В последнем уроке расскажем, как тестировать письма — так мы сможем убедиться, что всё работает и выглядит хорошо. 

Квиз

  1. Что подразумевает под собой резиновый подход к вёрстке?

— Размеры блоков указаны в процентах

— Размеры блоков указаны в пикселях

— Система сама вычисляет высоту блока пропорционально его размеру

  1. Для изображений шириной больше 300px…

— Нужно прописывать высоту в пикселях

— Не нужно прописывать фиксированную высоту

  1. Взгляните на код:

<img src=» main.png» width=»620″ alt=»Изображение» border=»0″ style=»display: block; width: 100%; max-width: 620px» />

Какое значение ширины увидят десктопные версии почтовиков?

— width: 100%; max-width: 620px

— width: 100%

— max-width: 620px

— width=»620″

  1.  Какой почтовик не видит медиа‑запросы?

— Outlook

— Google

— Яндекс

— Yahoo

  1. Сколько значений есть у свойства margin?

— 1

— 2

— 3

— 4

Домашнее задание

Наша первая вёрстка почти готова! Только письмо ещё нужно адаптировать к экранам смартфонов, чтобы при чтении рассылки с мобильного не пострадал ни один глаз. Вот что нужно сделать:

  1. Откройте в редакторе кода сохранённый ранее HTML-код письма.
  2. Последовательно адаптируйте код элементов всего письма, чтобы при открытии на экране смартфона ничего не «поехало». Для удобства используйте при работе меню разработчика. 
  3. Прикрепите файл с полученным кодом в комментарии к заданию.