Как стать автором
Обновить

Тестируем современные емейл-фреймворки

Уровень сложностиСредний
Время на прочтение10 мин
Количество просмотров6.6K

Все, кто сталкивался с версткой писем, знают, что там по-прежнему используется табличная верстка, инлайновые стили, css хаки, устаревшие теги и т.д. И все это ради поддержки всех (или, вернее сказать, большинства) почтовых клиентов: различных версий Outlook, веб-интерфейсов почтовиков и мобильных почтовых клиентов.

Но индустрия не стоит на месте - все активнее для верстки писем применяются емейл-фреймворки. О них и пойдет речь дальше. Сравним 2 из них: MJML и TJML framework (хотел добавить еще и Zurb Foundation for email, но они в последних публикациях уже не говорят о поддержке outlook, да и в принципе устарели).

MJML - самый известный и популярный емейл-фреймворк, признанный сообществом. На его основе работают всевозможные визуальные емейл-билдеры, и по факту он является стандартом в зарубежном емейл-маркетинге, хотя в России не все о нем знают.

TJML framework - это мой емейл-фреймворк, который создавался на основе личного многолетнего опыта работы в сфере емейл-маркетинга. В нем я постарался учесть все те проблемы и сложности, с которыми сталкивается верстальщик писем. Идея была в том, чтобы не просто обеспечить “приемлемое отображение” в большинстве клиентов”, а дать свободу верстальщику, при этом не обременяя его вопросами совместимости с устаревшими почтовыми клиентами. Ну и, плюс ко всему, дать возможность заложить в единый код как html, так и AMP-версию письма. Но в этой статье речь пойдет пока что только о html.

Чтобы сравнить эти емейл-фреймворки, сверстаем следующее письмо, а потом посмотрим на получившийся код и качество отображения в различных почтовых клиентах.

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

  • перестраивающиеся блоки (товарные карточки и заголовок с изображением на главном баннере);

  • масштабируемые блоки (в шапке письма);

  • использование фонового изображения (на баннере);

  • тексты;

  • кнопки.

Подключение и использование

MJML

Предоставляет несколько вариантов подключения на выбор:

  • playground прямо на сайте (самый простой и быстрый вариант для ознакомления);

  • приложение для Windows, Mac или Linux;

  • установка пакета через npm и использование его в привычной IDE;

  • готовые плагины для VSCode, Atom и Sublime Text.

TJML framework

Для продуктов JetBrains - phpStorm и webStorm - доступны подсказки и автокомплит через подключение web-types.json; также доступен плагин для VSCode.

Подготовительный этап

Для начала сделаем пустую заготовку письма:

MJML

<mjml>
  <mj-head>
	<mj-attributes>
  		<!-- укажем шрифт по-умолчанию -->
  		<mj-all font-family="Arial" />
	</mj-attributes>
  </mj-head>
  <mj-body width="600px" background-color="#ffffff">
	<!-- тело письма -->
  </mj-body>
</mjml>

Весь код письма обрамляется тегом <mjml>. Внутри присутствуют 2 раздела:<mj-head> - здесь мы по аналогии с html кодом задаем какие-то общие стили, заголовок страницы и значения атрибутов по-умолчанию, чтобы в дальнейшем их не указывать у каждого тега. Мы указали шрифт по-умолчанию - Arial  в коде. Раздел mj-head не является обязательным.<mj-body> - этот раздел содержит тело письма и является обязательным.

TJML framework

<tjml>
 <m-body bgcolor="#ffffff" font-family="Arial, sans-serif">
	<m-head preheader="текст, который отображается рядом с темой в списке входящих до открытия в почтовике"></m-head>
	<!-- тело письма -->  
 </m-body>
</tjml>

Здесь также есть общий обрамляющий тег <tjml>, внутри которого находится обязательный тег <m-body>,внутри которого уже находится все содержимое письма. Также в <m-body> может быть необязательный тег <m-head>, который позволяет задать параметры прехэдера письма. Параметры для текста по-умолчанию можно задать через атрибуты тега <m-body>.

Приступим к верстке

MJML

В MJML есть строгая иерархия блоков - что и во что можно вкладывать. Например, mj-column может быть только внутри mj-section или mj-group, а mj-section - внутри mj-body или mj-wrapper. Это сильно ограничивает доступные структуры, которые можно построить, а, следовательно, и дизайн.

Для вставки первого блока с фоновой картинкой воспользуемся тегом mj-wrapper, указав отступы, радиус скругления и фоновую картинку:

<mj-wrapper padding="30px 20px" border-radius="10px" background-url="img/bg.jpg">
	<!-- Содержимое блока -->
</mj-wrapper>

Логотип и номер телефона у нас вполне могут поместиться в строку на мобильном устройстве, поэтому сделаем масштабируемый (не перестраивающийся) блок. Для этого в mj-section необходимо добавить тег mj-group. В итоге получаем код:

<mj-section padding="0">
    <mj-group>
      	<mj-column vertical-align="middle">
        	<mj-image align="left" src="img/logo.png" padding="0" width="132px" height="22px" alt="transistor"></mj-image>
      	</mj-column>
      	<mj-column vertical-align="middle">
        	<mj-text align="right" font-size="16px" color="#ffffff" font-weight="bold" padding="0px" padding-top="0">
          	<a href="#" style="text-decoration: none;color:#ffffff;">+1 877-635-4243</a>
        	</mj-text>
      	</mj-column>
    </mj-group>
</mj-section>

Ниже в макете у нас заголовок и изображение ноутбука, которые необходимо перестраивать. Поэтому используем похожую структуру, но уже без mj-group.

<mj-section padding="30px 0 0">
    <mj-column vertical-align="middle">
      	<mj-text align="left" font-size="36px" color="#ffffff" padding="0px">
        	The best<br />laptop deals
      	</mj-text>
    </mj-column>
    <mj-column vertical-align="middle">
      	<mj-image align="left" src="img/img.png" padding="0" width="280px" height="168px"></mj-image>
    </mj-column>
</mj-section>

Блок с двумя товарами осложняется тем, что у товарных блоков есть фоновый цвет. И обычными инструментами расстояние между блоками сделать не получится. Нужно либо добавлять отступ через вспомогательный класс, либо использовать вставку произвольного html-кода. Оба этих решения несколько отходят от чистого использования фреймворка, поэтому сделаем отступ через дополнительную пустую колонку в 20 пикселей:

<mj-section padding="30px 0 20px">
  	<mj-column width="290px" background-color="#F5F5F7" padding="20px" border-radius="14px">
    	<mj-image align="center" src="img/item1.png" padding="0" width="180px" height="113px"></mj-image>
    	<mj-text align="center" font-size="22px" color="#222231" padding="10px 0 0">
      	$1,650.90
    	</mj-text>
    	<mj-text align="center" font-size="16px" color="#6a6a71" padding="5px 0 10px">
      	Laptop 15” 8GB Memory 512GB
    	</mj-text>
    	<mj-button background-color="#EA44A8" width="94px" height="40px" font-size="14px">
      	Buy
    	</mj-button>
  	</mj-column>
  	<mj-column width="20px"></mj-column>
  	<mj-column width="290px" background-color="#F5F5F7" padding="20px" border-radius="14px">
    	<mj-image align="center" src="img/item2.png" padding="0" width="180px" height="113px"></mj-image>
    	<mj-text align="center" font-size="22px" color="#222231" padding="10px 0 0">
      	$1,990.90
    	</mj-text>
    	<mj-text align="center" font-size="16px" color="#6a6a71" padding="5px 0 10px">
      	Tablet 11" 64GB Black
    	</mj-text>
    	<mj-button background-color="#EA44A8" width="94px" height="40px" font-size="14px">
      	Buy
    	</mj-button>
  	</mj-column>
</mj-section>

И остается только футер:

<mj-section>
   	 <mj-column>
 		<mj-text align="left" font-size="10px" color="#bababa" padding="0">
      	If you prefer not to receive emails like this, you may unsubscribe<br />
   		© 2023 Company. All rights reserved.
    	</mj-text>
  	</mj-column>
</mj-section>

TJML framework

Здесь нет жесткой иерархии элементов. Фреймворк оперирует тремя абстракциями, на основе которых строится структура:

  • обертка (m-wrap) - применяется для задания фона, рамки, отступов и т.д., ограничения размера или же для указания выравнивания;

  • перестраивающиеся блоки (m-boxes и m-box);

  • Не перестраивающиеся блоки (m-row и m-column).

Данный подход позволяет реализовать в рамках письма любую структуру. Помимо тегов, отвечающих за структуру, есть текст (m-text), кнопка (m-button), картинка (m-img) и другие.

У первого блока есть фоновое изображение и закругления. Для его вставки будем использовать тег <m-wrap> с атрибутами background-image, border-radius, а также зададим альтернативный фоновый цвет через bgcolor и отступы через padding.

<m-wrap width="600" padding="30px 20px" bgcolor="#D547A0" background-image="img/bg.jpg" border-radius="10px">
	<!-- тело письма -->  
</m-wrap>

Блоки, которые должны сжиматься, зададим через конструкцию не перестраивающихся блоков - m-row и m-column

<m-row width="100%">
	<m-column align="left">
		<m-img src="img/logo.png" width="132" height="22" alt=""></m-img>
	</m-column>
	<m-column align="right" valign="middle">
		<m-text href="#" color="#ffffff" bold font-size="16px">+1 877-635-4243</m-text>
	</m-column>
</m-row>

Перестраивающиеся блоки заголовка и изображения ноутбуков можно сделать через конструкцию m-boxes и m-box

<m-boxes align="left" valign="middle">
	<m-box width="280" align="left">
		<m-text color="#ffffff" font-size="36px">
			The best<br />laptop deals
		</m-text>
	</m-box>
	<m-box width="280">
		<m-img src="img/img.png" width="280" height="168" alt=""></m-img>
	</m-box>
</m-boxes>

Товарные карточки также представляют из себя перестраивающиеся блоки. Для отступов  будем использовать вложенные m-wrap с заданием желаемых размеров и фона.

<m-wrap width="620">
<m-boxes>
	<m-box width="310">
		<m-wrap width="290" bgcolor="#F5F5F7" border-radius="14px" padding="20px">
			<m-img src="img/item1.png" width="180" height="113" alt=""></m-img>
			<m-wrap padding="10px 0">
				<m-text color="#222231" font-size="22px" line-height="26px">$1,650.90</m-text>
				<m-text color="#6A6A71" font-size="16px" line-height="20px">Laptop 15” 8GB Memory 512GB</m-text>
			</m-wrap>
			<m-button color="#ffffff" border-radius="6px" bgcolor="#EA44A8" width="94" height="40">Buy</m-button>
		</m-wrap>
		<m-padding size="20"></m-padding>
	</m-box>
	<m-box width="310">
		<m-wrap width="290" bgcolor="#F5F5F7" border-radius="14px" padding="20px">
			<m-img src="img/item2.png" width="180" height="113" alt=""></m-img>
			<m-wrap padding="10px 0">
				<m-text color="#222231" font-size="22px" line-height="26px">$1,990.90</m-text>
				<m-text color="#6A6A71" font-size="16px" line-height="20px">Tablet 11" 64GB Black</m-text>
			</m-wrap>
			<m-button color="#ffffff" border-radius="6px" bgcolor="#EA44A8" width="94" height="40">Buy</m-button>
		</m-wrap>
		<m-padding size="20"></m-padding>
	</m-box>
</m-boxes>
</m-wrap>

И остался футер

<m-wrap width="620" padding="20px 10px" align="left">
    <m-text font-size="10px" color="#BABABA">
    If you prefer not to receive emails like this, you may unsubscribe<br />
    © 2023 Company. All rights reserved.
    </m-text>
</m-wrap>

Сравниваем результаты

Главное в подобном инструменте - это конечно, отрендеренная (собранная) верстка: качество кода, его размер, читаемость и кроссплатформенность.

Размер кода

Начнем с размеров. Почему это важный показатель? Дело в том, что Gmail обрезает письма, которые превышают 102kb. Это не только сломает письмо визуально, но и не позволит отследить открытия таких писем, так как трекинг-пиксели обычно добавляются в самом конце перед закрывающим body. То есть вы получите заниженные показатели OR.
Для сравнения сжатия будем использовать встроенные инструменты сжатия каждого из фреймворков:

MJML

TJML framework

Без сжатия

22 Кб

14,1 Кб

С сжатием

14,8 Кб

10,7 Кб

Отображение в разных почтовиках

Для начала сравним отображение в веб-интерфейсе Gmail:

отображение в Gmail
отображение в Gmail

Здесь оба фреймворка показали себя хорошо. Попробуем что-нибудь посложнее - например, отображение в десктопном приложении Outlook, как в самом “капризном” почтовом клиенте:

Отображение в Outlook
Отображение в Outlook

Здесь разница отображения уже сильно заметна. Главным образом в MJML мы видим проблемы с отступом у блока с фоновым изображением. Это связано с особенностями Outlook при обработке padding внутри vml (именно vml используется в обоих фреймворках для отображения фоновых изображений для Outlook. Вообще, vml - это язык векторной разметки документа от Microsoft).

Также заметна разница в отображении кнопок. В TJML framework для кнопок используется vml (где это возможно), поэтому мы видим четкое соответствие макету по размерам и сохранение закруглений. В MJML используется ячейка таблицы. В данном случае мы видим дополнительные отступы, которые появились у этой ячейки, что увеличило высоту кнопок.

Часто можно услышать - “Да кому нужен этот аутлук? Им никто не пользуется”. Да, для b2c рассылок, в среднем, на открытия с Outlook приходится менее 5%. Но картина резко меняется, если мы говорим про b2b рассылки. А также, по опыту работы в агентстве, могу заметить, что зачастую сам заказчик использует именно Outlook, и присланные тесты смотрит именно в нем.

В MJML используется подход “mobile first”. То есть структура изначально соответствует мобильной версии письма, а с помощью медиа-запросов уже формируется десктопная версия. Подход неплохо работает в большинстве почтовых клиентов и обеспечивает отличное отображение в мобильных приложениях даже без поддержки медиа-запросов. Однако в России очень популярна Yandex-почта, которая занимает 2 место после mail.ru, и при этом не поддерживает медиа-запросы - ни в веб интерфейсе, ни в мобильных приложениях.

Отображение в Yandex-почте
Отображение в Yandex-почте

Для полноты картины также стоит показать мобильную адаптацию:

отображение на iPhone в стандартном приложении Почта
отображение на iPhone в стандартном приложении Почта

TJML framework, наоборот, не использует медиа-запросы для адаптации по умолчанию. Поэтому мы видим карточки исходного размера, а не на всю ширину, как в MJML. При необходимости это можно изменить, используя классы и медиа-запросы в разделе m-style. Также заметно, что отличается выравнивание фонового изображения по умолчанию. Как в MJML, так и в TJML framework его можно изменить с помощью соответствующего атрибута.

Дополнительные инструменты

MJML

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

  • mj-accordion для создания аккордеонов;

  • mj-carousel для создания каруселей.

Но эти элементы мало где работают  - главным образом только в стандартном приложении почты на iPhone и на Mac.

Это проект имеет открытый исходный код и активно поддерживается сообществом, поэтому можно найти большое количество компонентов, например:

  • mj-chart для добавления графиков;

  • mj-qr-code - для добавления QR-кодов.

TJML framework

Главным отличием от всех прочих емейл-фреймворков является то, что он формирует не только html версию письма, но также AMP и поддерживает ряд AMP-компонентов (карусели, аккордеоны, формы, amp-листы). И в отличие от MJML они будут работать в почтовых клиентах от gmail, mail.ru и yahoo (при выполнении ряда требований, но в особенности AMP здесь вдаваться не буду).

Для разработчика также есть вспомогательные инструменты для достижения наилучшего результата за минимальное время: 

  • инструмент pixel perfect - наложение макета под верстку с одним из режимов смешивания для точной верстки “пиксель в пиксель”;

  • тестирование темной темы.
    С появлением темной темы и автоматическим перекрашиванием писем в мобильных почтовых клиентах у верстальщиков и дизайнеров появилась еще одна проблема. И как обычно это бывает - у всех это перекрашивание работает немного по разному. Поэтому при разработке вспомогательных инструментов фреймворка я сделал особый акцент на это и предусмотрел 2 варианта -  обычная темная тема (с инверсией яркости у светлых элементов), а также режим полной инверсии яркости, характерный для Gmail на iOS (он изначально темные письма перекрашивает в светлые).

TJML фреймворк доступен без каких-либо ограничений и поможет как значительно сократить время на разработку писем, так и снизить порог вхождения в емейл-верстку. Я постарался вложить свой опыт в сфере емейл-маркетинга и емейл-верстки в инструмент который поможет абстрагироваться от привычных емейл костылей, вроде условных комментариев, vml и табличной верстки и оперировать уже структурными элементами. А также позволит стереть границу между интерактивными amp и статичными html письмами. Но это уже тема для другой статьи).

Я продолжаю развивать этот инструмент и буду рад, если он окажется полезен).

Проект на github.

Теги:
Хабы:
Всего голосов 4: ↑3 и ↓1+5
Комментарии11

Публикации

Истории

Ближайшие события

7 – 8 ноября
Конференция byteoilgas_conf 2024
МоскваОнлайн
7 – 8 ноября
Конференция «Матемаркетинг»
МоскваОнлайн
15 – 16 ноября
IT-конференция Merge Skolkovo
Москва
22 – 24 ноября
Хакатон «AgroCode Hack Genetics'24»
Онлайн
28 ноября
Конференция «TechRec: ITHR CAMPUS»
МоскваОнлайн
25 – 26 апреля
IT-конференция Merge Tatarstan 2025
Казань