MJML или TJML: испытываем емейл-фреймворки на практике
Создание электронных писем, которые корректно отображались бы во всех почтовых клиентах, было настоящей головной болью. Табличная верстка, устаревшие теги и CSS-хаки были неотъемлемой частью этого процесса.
Сейчас все изменилось: появились емейл-фреймворки, которые упрощают эту задачу. В этом обзоре мы рассмотрим два из них: MJML и TJML, чтобы определить, какой лучше подходит для создания эффективных email-рассылок.
Что это за фреймворки?
MJML — это наиболее популярный фреймворк для писем. Он лежит в основе многих визуальных конструкторов и фактически стал стандартом международного емейл-маркетинга, хотя в России не так известен.
TJML — это фреймворк от Pixcraft, созданный на основе богатого опыта в email-маркетинге. Это инструмент, который решает многие проблемы, с которыми сталкиваются верстальщики ежедневно.
С TJML вы можете не беспокоиться о совместимости с разными почтовыми клиентами и сосредоточиться на создании красивых и адаптивных писем. Кроме того, TJML позволяет объединить в одном коде HTML и AMP-версии письма.
Какой фреймворк выбрать?
Чтобы разобраться, давайте на практике попробуем каждый из них. После этого проанализируем полученный код и оценим качество отображения письма в различных почтовых клиентах.
Сверстаем письмо, включающее в себя адаптивные блоки (товарные карточки и баннеры с заголовками), масштабируемые блоки (элементы шапки письма), фоновые изображения, текст и кнопки.
Подключаем фреймворк
Как подключать MJML:
- Онлайн-песочница. Самый простой способ попробовать MJML — это воспользоваться онлайн-редактором прямо на сайте. Подойдёт для тех, кто хочет быстро ознакомиться с возможностями фреймворка или создать простой емейл.
- Десктопная версия. Для более масштабных задач предлагается приложение для основных операционок (Windows, macOS, Linux).
- Плагины. Если вы пользуетесь популярными редакторами кода, такими как VSCode, Atom или Sublime Text, то для MJML есть специальные плагины.
- Установка через npm. MJML можно установить через npm и использовать в любой удобной среде разработки.
Как подключить TJML:
Онлайн-песочница. Используйте playground для быстрого создания и тестирования писем. Можно писать код, сразу видеть результат и быстро вносить правки, не выходя из браузера.
Подключение как JS-библиотеки. Если вы предпочитаете работать в привычной среде разработки, то можете подключить JS-библиотеку. Все инструкции по подключению вы найдете в документации.
Плагин для VSCode. Это расширение предлагает автозаполнение и всплывающие подсказки для всех тегов и атрибутов TJML.
Автокомплит для PhpStorm и WebStorm через Web-Types. Вы можете подключить web-types.json, чтобы получить подсказки по тегам и доступным атрибутам.
Готовимся к верстке
Начнем с пустой заготовки емейла.
С MJML:
1 2 3 4 5 6 7 8 9 10 11
<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>
. Внутри есть два раздела: <mj-head>
и <mj-body>
.
- В необязательном разделе
<mj-head>
задаются общие стили, заголовок страницы и значения атрибутов по умолчанию, что позволяет не указывать их для каждого тега. В нашем примере установлен шрифт по умолчанию — Arial. - Тег
<mj-body>
содержит основное содержание письма и является обязательным элементом структуры.
C TJML:
1 2 3 4 5 6
<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>
. Задаем отступы, радиус скругления и изображение.
1 2 3
<mj-wrapper padding="30px 20px" border-radius="10px" background-url="img/bg.jpg"> <!-- Содержимое блока --> </mj-wrapper>
Лого и номер телефона поместятся в одной строке на мобильном устройстве, поэтому создадим масштабируемый блок, который не будет перестраиваться. В <mj-section>
добавим <mj-group>
.
Что получается в итоге:
1 2 3 4 5 6 7 8 9 10 11 12
<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.
1 2 3 4 5 6 7 8 9 10
<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 />choice </mj-text> </mj-column> <mj-column vertical-align="middle"> <mj-image align="left" src="img/img.png" padding="0" width="280px" height="234px"></mj-image> </mj-column> </mj-section>
Блок с двумя товарами сложнее из-за фонового цвета у товарных карточек. Простым способом задать расстояние между ними нельзя.
Есть два варианта: добавлять отступ с помощью вспомогательного класса или вставлять собственный HTML-код.
Оба этих метода выходят за рамки стандартного использования фреймворка, поэтому добавим отступ, вставив пустую колонку шириной в двадцать пикселей.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
<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="116px"></mj-image> <mj-text align="center" font-size="22px" color="#222231" padding="10px 0 0"> $1,560.90 </mj-text> <mj-text align="center" font-size="16px" color="#6a6a71" padding="5px 0 10px"> Game console White </mj-text> <mj-button background-color="#6a66d3" width="94px" height="40px" font-size="14px"> Buy </mj-button> </mj-column> <mj-column width="20px"><mj-text></mj-text></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="116px"></mj-image> <mj-text align="center" font-size="22px" color="#222231" padding="10px 0 0"> $1,890.90 </mj-text> <mj-text align="center" font-size="16px" color="#6a6a71" padding="5px 0 10px"> Monitor 27” IPS LED FHD </mj-text> <mj-button background-color="#6a66d3" width="94px" height="40px" font-size="14px"> Buy </mj-button> </mj-column> </mj-section>
Дальше идет футер.
1 2 3 4 5 6 7 8
<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 /> © 2024 Company. All rights reserved. </mj-text> </mj-column> </mj-section>
С TJML:
В этом фреймворке жёсткая иерархия элементов отсутствует. Он предлагает три основные абстракции для создания структуры:
- обертка (m-wrap), которая задает фон, рамки, отступы, ограничения по размеру и выравнивание;
- перестраивающиеся блоки (m-boxes и m-box);
- не перестраивающиеся блоки (m-row и m-column).
Такой подход обеспечивает гибкость в создании структуры письма. Помимо структурных тегов, доступны такие элементы, как текст (m-text), кнопка (m-button), изображение (m-img) и другие.
Первый блок требует фонового изображения и скругленных углов. Используем тег <m-wrap>
, задав атрибуты background-image, border-radius, а также альтернативный цвет (bgcolor) и отступы (padding).
1 2 3
<m-wrap width="600" padding="30px 20px" bgcolor="#473fac" background-image="img/bg.jpg" border-radius="10px"> <!-- тело письма --> </m-wrap>
Блоки, требующие сжатия, задаются с использованием m-row и m-column.
1 2 3 4 5 6 7 8
<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.
1 2 3 4 5 6 7 8 9 10
<m-boxes align="left" valign="middle"> <m-box width="280" align="left"> <m-text color="#ffffff" font-size="36px"> The best<br />choice </m-text> </m-box> <m-box width="280"> <m-img src="img/img.png" width="280" height="234" alt=""></m-img> </m-box> </m-boxes>
Карточки товаров тоже являются перестраивающимися блоками. Чтобы задать отступы, применим вложенные m-wrap с нужными размерами и фоновым цветом.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
<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="116" alt=""></m-img> <m-wrap padding="10px 0"> <m-text color="#222231" font-size="22px" line-height="26px">$1,560.90</m-text> <m-text color="#6A6A71" font-size="16px" line-height="20px">Game console White</m-text> </m-wrap> <m-button color="#ffffff" border-radius="6px" bgcolor="#6a66d3" 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="116" alt=""></m-img> <m-wrap padding="10px 0"> <m-text color="#222231" font-size="22px" line-height="26px">$1,890.90</m-text> <m-text color="#6A6A71" font-size="16px" line-height="20px">Monitor 27” IPS LED FHD</m-text> </m-wrap> <m-button color="#ffffff" border-radius="6px" bgcolor="#6a66d3" width="94" height="40">Buy</m-button> </m-wrap> <m-padding size="20"></m-padding> </m-box> </m-boxes> </m-wrap>
И, наконец, идет футер.
1 2 3 4 5 6
<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 /> © 2024 Company. All rights reserved. </m-text> </m-wrap>
Что получилось
Ключевым аспектом фреймворка является качество готовой верстки, включая чистоту кода, его объем, читаемость и отображение в различных почтовых клиентах.
Размер
Gmail автоматически обрезает письма, если их размер превышает 102 КБ. Это не только испортит внешний вид, но и затруднит отслеживание OR, так как пиксели для трекинга обычно добавляются в конце перед закрывающим тегом <body>
. Т.е. «раздутый» код приведет к снижению статистики открытий.
Для оценки сжатия используем встроенные инструменты сжатия каждого фреймворка.
TJML | MJML | |
Сжатый код | 11,17 КБ | 14,84 КБ |
Несжатый код | 13,52 КБ | 22,35 КБ |
Как отображается в разных почтовых клиентах
В Gmail:
Теперь давайте попробуем что-то более сложное — например, посмотрим, как письмо выглядит в десктопной версии Outlook. Проблемы с отображением в этой программе — явление довольно частое.
Для B2C-рассылок отображение в Outlook может быть не столь критичным, т.к. в среднем его показатель открытий не превышает 5%. Однако в контексте B2B-рассылок наблюдается совершенно иная картина. Кроме того, заказчики зачастую проверяют тестовые письма именно в Outlook. Поэтому пренебрегать этим почтовиком не стоит.
В этом случае различия в отображении становятся очевидными. В MJML мы сталкиваемся с проблемами отступов у блока с фоном. Это происходит из-за специфики работы Outlook с padding внутри VML.
Кнопки тоже отображаются по-разному. В TJML для их создания по возможности используется VML, что позволяет добиться точного соответствия размерам макета и сохранить закругленные углы. В MJML кнопки формируются с помощью таблицы, из-за чего высота кнопок увеличивается из-за дополнительных отступов.
В фреймворке MJML применяется принцип «mobile first», что означает, что структура письма изначально ориентирована на мобильные устройства, а версия для десктопов создается с помощью медиа-запросов. Принцип показывает неплохие результаты во многих почтовых клиентах и позволяет добиться качественного отображения на мобильных устройствах, даже если медиа-запросы не поддерживаются. Однако стоит учитывать, что Yandex не поддерживает медиа-запросы ни в своей веб-версии, ни в мобильных приложениях — а этот почтовый сервис занимает второе место по популярности в России.
Десктопная версия Yandex:
Мобильная версия:
В отличие от MJML, TJML изначально не применяет медиа-запросы для адаптации. Поэтому карточки отображаются в своем исходном размере, а не растягиваются на весь экран. При желании это можно исправить, добавив классы и медиа-запросы в m-style.
Также отличается выравнивание фона. В обоих фреймворках, MJML и TJML, его легко изменить, используя соответствующий атрибут.
Какие еще есть инструменты
Фреймворк TJML отличается от других тем, что создает не только HTML-версию письма, но и AMP-версию, поддерживающую такие AMP-компоненты, как карусели, аккордеоны, формы и списки AMP и др. В отличие от MJML, эти элементы будут корректно работать в почтовых клиентах Gmail, Mail.ru,Yahoo и AOL.
Также есть дополнительные инструменты для удобства:
- Pixel Perfect позволяет убедиться, что каждый элемент на экране расположен точно так, как было задумано дизайнером, вплоть до отдельного пикселя. Пользователи могут загружать графические макеты и регулировать их прозрачность, чтобы визуально сопоставить с версткой. Это позволяет разработчикам точно подстраивать размеры, отступы и другие параметры, добиваясь идеального совпадения «пиксель в пиксель» между дизайном и реализацией.
- Тестирование темной темы. Поскольку многие пользователи мобильных устройств предпочитают темное оформление, возникла необходимость адаптировать электронные письма под почтовые клиенты, которые по-разному реализуют эту функцию. Для решения этой задачи мы добавили два режима отображения в темной теме: стандартный (с инверсией светлых элементов) и режим полной инверсии, аналогичный Gmail для iOS.
Заключение
Использование email-фреймворков в значительной степени позволяет ускорить и упростить процесс верстки писем, при этом позволяет гибко управлять структурой и отображением.
TJML — это практичное и удобное решение для создания емейлов, ориентированное на реальные потребности верстальщиков. По сравнению с MJML, TJML обеспечивает больше свободы в работе и позволяет избежать проблем с совместимостью с устаревшими почтовыми клиентами. Он также дает возможность создавать как HTML, так и AMP-версии в одном коде.
Если вы ищете инструмент, который упростит процесс разработки, TJML станет отличным выбором для вашего бизнеса.