Подумайте об использовании инлайна CSS в вашем следующем email проекте

Подумайте об использовании инлайна CSS в вашем следующем email проекте

От автора: у новичков в email разработке возникают три главные проблемы, с которыми вы, скорее всего, уже столкнулись: в email шаблонах почти всегда банятся внешние ресурсы, вся разметка построена на таблицах, а также необходим инлайн CSS. В этой статье мы поговорим о последнем пункте и узнаем, почему и как это сделать.

Вы уже знаете, что необходимость инлайнить CSS изменилась с тех пор, как Gmail начал поддерживать тег style. Тем не менее, эта техника все еще широко применяется в региональных клиентах электронной почты и в некоторых нативных приложениях почты для старых устройств на андроид, а также в старых приложениях Gmail. Инлайнинг отлично подходит для сложных макетов. Инлайнинг может послужить основой для техник прогрессивного улучшения.

Решив, что это важно, давайте поговорим о доступных онлайн инструментах и инструментах командной строки.

Ниже мы обсудим разные инструменты, узнаем их плюсы, а также минусы. Задача – чтобы после прочтения статьи вы могли легко использовать их и замечать в них недостатки.

Общие моменты при инлайнинге CSS

Инлайнинг – широко применяемый метод конвертирования вставляемых и внешних CSS стилей в более надежный email код. Процесс похож с последним Email в ежегодной коллекции на сайте Acid. Отличный способ поддерживать старые и менее развитые email клиенты.

Практический курс по верстке адаптивного лендинга с нуля!

Научитесь с нуля верстать адаптивные лендинги на HTML5 и CSS3 за ближайшие 6 дней

Узнать подробнее

До сих пор продолжаются споры по поводу отказа от инлайн стилей в будущем – можно заключить, что все до сих пор зависит от email клиентов конечных пользователей.

Возьмем шаблон из предыдущего урока по использованию препроцессора Sass в email разработке. Сравним вставляемые стили…

Подумайте об использовании инлайна CSS в вашем следующем email проекте

И инлайн…

Подумайте об использовании инлайна CSS в вашем следующем email проекте

Версии одного и того же шаблона. Скриншоты сняты с T-Online.de, что ясно показывает, если этот клиент важен для вас, вам нужно использовать инлайн стили для его поддержки. Outlooks на основе Word и разные версии Lotus Notes также лучше работают с инлайн стилями.

Множество email разработчиков инлайнит CSS вручную, но сразу понятно, что такой подход занимает много времени, и могут возникать ошибки. Здесь могут сильно пригодиться CSS инлайнеры. Но существует ли идеальный инструмент для этого?

Это вам нужно решить для себя самому. У разных инструментов свою сильные и слабые стороны. Ваша задача и конечный результат определят правильный ответ.

Из статьи Julie Ng возьмем предварительные условия для CSS инлайнеров:

Не менять HTML

Не удалять условные комментарии

Не сцеплять несколько CSS свойств в сокращение

Инлайнить и подключать только определенный CSS

Запомните эти условия. Перейдем к подробному разбору.

Начало работы с инлайнерами CSS

Если поискать в сети инлайн инструменты, можно найти 4 других варианта ручного инлайнинга:

Онлайн сервисы типа Litmus’s Putsmail, Mailchimp Inliner, Zurb Foundation’s CSS Inliner и Campaing Monitor’s Inliner.cm

API, где вы посылаете HTML и CSS и получаете инлайн версию документа

Инструменты командной строки типа ruby gems и глобально установленные пакеты NPM

CSS инлайнеры есть в таск раннер плагинах

Далее рассмотрим примеры описанных выше вариантов.

CSS инлайнеры через командную строку

Начнем с простейшего инструмента, но вы увидите, что он потрясающе справляется со своей задачей. Инструмент называется Inlining. Доступен на Github и NodeJS package manager.

Инлайн стили должны быть в отдельном CSS файле. При инлайнинге CSS мы применим следующие стили:

body, p {
 margin: 0;
 padding: 0;
 margin-bottom: 0;
 -webkit-text-size-adjust: none;
 -ms-text-size-adjust: none; }

 table {
 border-spacing: 0;
 mso-table-lspace: 0pt;
 mso-table-rspace: 0pt; }
 table td {
 border-collapse: collapse; }

 .ExternalClass, 
 .ExternalClass p, 
 .ExternalClass span, 
 .ExternalClass font, 
 .ExternalClass td, 
 .ExternalClass div {
 line-height: 100%; }

 .ReadMsgBody {
 width: 100%; }

 img {
 -ms-interpolation-mode: bicubic; }

 p,
 h1,
 h2,
 h3,
 h4,
 h5,
 h6 {
 font-family: Arial; }

 /* default font sizes */
 h1 {
 font-size: 28px;
 line-height: 32px;
 padding-top: 10px;
 padding-bottom: 24px; }

 ...

 Additional heading and paragraph styles

 ...

 .container {
 width: 600px; }

 .hero {
 background-color: #71b47b;
 color: black; }
 .hero .alternate-background {
 background-color: #b471aa; }
 .hero .col33 {
 width: 33%; }
 .hero .col67 {
 width: 67%; }
 .hero .col50 {
 width: 50%; }

 @media only screen and (max-width: 599px) {
 .container, .col33, .col67, .col50 {
 width: 100% !important; } }
 .button, .button-primary, .button-secondary {
 font-family: sans-serif;
 font-size: 13px;
 font-weight: bold;
 text-align: center;
 text-decoration: none;
 display: inline-block;
 -webkit-text-size-adjust: none;
 border: 1px solid #1e3650;
 border-radius: 4px;
 background-color: #ccdd22;
 color: #ffffff;
 width: 200px;
 line-height: 40px; }
 .button-primary {
 background-color: #ffbbcc;
 color: #ffffff;
 width: 250px;
 line-height: 50px; }
 .button-secondary {
 background-color: #7733cc;
 color: #ffffff;
 width: 150px;
 line-height: 30px; }

Экосистему NodeJS, а также как устанавливать NPM пакеты мы представили в предыдущем уроке. Быстро вспомним предыдущую статью. Следуя шагам установки:

npm install -g inlining

вы должны легко установить Inlining.

Если у вас возникли проблемы, которые вы не можете решить сами, пишите об этом в комментариях, мы поможем.

После глобальной установки с помощью следующей команды inlining input.html >output.html можно инлайнить стили. Результат обработки input.html будет помещен в файл output.html. Используя тестовый шаблон, мы получим HTML ниже:

<!DOCTYPE html><html><head> 
 <title>One column layout</title>
<link>

<style>/* default font sizes */

@media only screen and (max-width: 599px) {
  .container, .col33, .col67, .col50 {
 width: 100% !important; } }</style></head>

<body style="margin:0;padding:0;margin-bottom:0;-webkit-text-size-adjust:none;-ms-text-size-adjust:none;background-color:#F4F4F4;"> 
 <table width="100%" cellpadding="0" cellspacing="0" style="border-spacing:0;mso-table-lspace:0pt;mso-table-rspace:0pt;min-width:100%;">
 <tbody><tr>
 <td width="100%" style="border-collapse:collapse;min-width:100%;">
 <center>
 <table class="container" cellpadding="0" cellspacing="0" width="600" style="border-spacing:0;mso-table-lspace:0pt;mso-table-rspace:0pt;width:600px;margin:0 auto;">
 <tbody><tr>
 <td width="100%" style="border-collapse:collapse;text-align:left;">

 <!-- header with image -->
 <table width="100%" cellpadding="0" cellspacing="0" style="border-spacing:0;mso-table-lspace:0pt;mso-table-rspace:0pt;min-width:100%;">
 <tbody><tr>
 <td width="100%" style="border-collapse:collapse;min-width:100%;background-color:#FFFFFF;color:#000000;padding:30px;">
 <img alt="wonderful EDM logo" src="https://edmdesigner.github.io/modern-html-email-tutorial/lesson03/img/logo.png" width="210" style="-ms-interpolation-mode:bicubic;display: block;">
 </td>
 </tr>
 </tbody></table>

 <table class="hero" width="100%" cellpadding="0" cellspacing="0" style="border-spacing:0;mso-table-lspace:0pt;mso-table-rspace:0pt;background-color:#71b47b;color:black;min-width:100%; ">
 <tbody><tr>
 <td width="100%" style="border-collapse:collapse;min-width:100%;padding:20px;">

 <!-- Hero image -->
 <table class="col33" align="left" cellpadding="0" cellspacing="0" border="0" width="100%" style="border-spacing:0;mso-table-lspace:0pt;mso-table-rspace:0pt;width:33%;">
 <tbody><tr>
 <td width="100%" align="center" style="border-collapse:collapse;">
 <img alt="wonderful Sass logo" src="https://pbs.twimg.com/profile_images/583681608269471744/jCR2zNJV_200x200.png" style="-ms-interpolation-mode:bicubic;display: block; max-width: 100%;">
 </td>
 </tr>
 </tbody></table>

 <!-- H1 -->
 <table class="col67 alternate-background" align="left" cellpadding="0" cellspacing="0" border="0" width="100%" style="border-spacing:0;mso-table-lspace:0pt;mso-table-rspace:0pt;background-color:#b471aa;width:67%;">
 <tbody><tr>
 <td width="100%" style="border-collapse:collapse;">
 <!-- H1 -->
 <table cellpadding="0" cellspacing="0" border="0" width="100%" style="border-spacing:0;mso-table-lspace:0pt;mso-table-rspace:0pt;">
 <tbody><tr>
 <td align="center" style="border-collapse:collapse;">
 <h1 style="font-family:Arial;font-size:28px;line-height:32px;padding-top:10px;padding-bottom:24px;">
 Email coding is the best
 </h1>
 </td>
 </tr>
 </tbody></table>
 </td>
 </tr>
 </tbody></table>

 ....

 <!-- Button -->
 <table class="col67" align="left" cellpadding="0" cellspacing="0" border="0" width="100%" style="border-spacing:0;mso-table-lspace:0pt;mso-table-rspace:0pt;width:67%;">
 <tbody><tr>
 <td width="100%" style="border-collapse:collapse;">
 <table cellpadding="0" cellspacing="0" border="0" width="100%" style="border-spacing:0;mso-table-lspace:0pt;mso-table-rspace:0pt;">
 <tbody><tr>
 <td align="center" style="border-collapse:collapse;">
 <div>
 <a class="button-secondary" href="https://edmdesigner.com" target="_blank" style="font-family:sans-serif;font-size:13px;font-weight:bold;text-align:center;text-decoration:none;display:inline-block;-webkit-text-size-adjust:none;border:1px solid #1e3650;border-radius:4px;background-color:#ccdd22;color:#ffffff;width:200px;line-height:40px;background-color:#7733cc;color:#ffffff;width:150px;line-height:30px;">
 Show me a button!
 </a>
 </div>
 </td>
 </tr>
 </tbody></table>
 </td>
 </tr>
 </tbody></table>

 </td>
 </tr>
 </tbody></table>

 <!-- footer -->
 <table width="100%" cellpadding="0" cellspacing="0" style="border-spacing:0;mso-table-lspace:0pt;mso-table-rspace:0pt;min-width:100%;">
 <tbody><tr>
 <td width="100%" style="border-collapse:collapse;min-width:100%;background-color:#58585A;color:#FFFFFF;padding:30px;">
 <p style="margin:0;padding:0;margin-bottom:0;-webkit-text-size-adjust:none;-ms-text-size-adjust:none;font-family:Arial;font-size:17px;line-height:20px;padding-top:6px;padding-bottom:15px;font-size:16px;line-height:20px;font-family:Georgia,Arial,sans-serif;text-align:center;">2017 @ COPYRIGHT - EDMDESIGNER</p>
 </td>
 </tr>
 </tbody></table>

 </td>
 </tr>
 </tbody></table>
 </center>
 </td>
 </tr>
 </tbody></table>


</body></html>

Стоит объяснить пару моментов по этому инструменту:

Он оставляет медиа запросы в теге style – вы увидите, что не все инструменты делают это

Хорошо инлайнит свойства width классов макета col67, col33

Добавляет тег tbody, завершая разметку table

Удаляет неизвестные CSS классы типа ExternalClass

Изучив превью Litmus, можно сделать вывод, что правильный жидкий макет применяется в большинстве мобильных email клиентов, а десктоп представление отображается на десктопе и webmail клиентах. В инструменте нет кастомизации процесса инлайнинга, но мне и так нравится результат. Мне не понравилось два момента: 1 – инструмент умеет инлайнить CSS только из внешних стилей, 2 – он использует табуляцию, что усложняет изменение после инлайнинга. В целом, я рекомендую этот инструмент.

Настройка инструмента автоматизации

Когда я захотел протестировать разные инструменты по инлайнингу, я узнал, что есть только один эффективный способ – собрать их и запустить через скрипт. Работать будет любое решение, но для упрощения нашей работы есть специальные инструменты, таск раннеры. Так мне нужно будет править только HTML, CSS и настройки инлайнеров CSS, остальные части процедуры сделают за меня.

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

Мы выберем Gulp – часто используемый, быстрый JS таск раннер. По простой стандартной команде мы создадим все команды запуска разных CSS инлайнеров. Установка такая же, как в разделе про Inlining.

Детально автоматизацию задач мы разберем в следующей статье по созданию автоматизированного фреймворка по созданию email. Все же, вас нужно познакомить с популярным JS таск раннером чисто для этой статьи. Поехали!

Рекомендуемые настройки проекта можете скачать с Github, но я все же быстро расскажу, как все работает. Если у вас возникли предложения по улучшению, пишите в комментариях.

В нашем проекте у нас будут:

input.html – хранит разметку шаблона email и тег link на main.css, в котором лежат стили шаблона, или же встраиваемые стили в тег style. В этом теге мы и будем тестировать принцип работы

gulpfile.js – хранит все задачи по инлайнингу

Практический курс по верстке адаптивного лендинга с нуля!

Научитесь с нуля верстать адаптивные лендинги на HTML5 и CSS3 за ближайшие 6 дней

Узнать подробнее

файлы и папки NPM – файл package.json и папка node_modules – здесь будут размещены gulp util пакеты (например, gulp-rename для настройки имени выходного файла) и пакеты CSS inliner, доступные через NPM

Я открыл отдельные JS файлы для каждого CSS инлайнера, который не настроен на прямой запуск с Gulp

Папка results – хранит сгенерированный инлайновый HTML

Все вместе выглядит так:

inliner-tasks/
 |_ node_modules/
 |
 |_ results/
 | |
 | |_<inlined result files>
 |
 |
 |_ input.html
 |
 |_ gulpfile.js
 |
 |_ package.json

Перейдем в терминале в рабочую папку и установим все, что будем использовать:

Нужно выполнить команду npm install —save gulp-premailer gulp-juice gulp-email-builder.

После выполнения переходим к заполнению gulpfile. Для экономии места я показываю задачу для одного инлайнера.

// REQUIRING NECESSARY PACKAGES
 var gulp = require('gulp');
 // this package let's us run command-line
 // commands from the Gulp JavaScript file
 var run = require("gulp-run-command").default;
 var rename = require("gulp-rename");

 // INLINER PACKAGES
 // ========================================
 var gulpPremailer = require("gulp-premailer");
 var gulpJuice = require("premailer-gulp-juice");
 var emailBuilder = require('gulp-email-builder');

 // FILE PATHS
 // ========================================
 var input = "input.html";
 var output = "results/";

 // INLINER TASKS
 // ========================================

 // Premailer
 var premailerRunFile = "premailer/pre.rb"
 var rubyCommand = "ruby ";

 var premailer = rubyCommand + premailerRunFile;

 // Gulp-premailer
 gulp.task("gPremailer", function () {
 gulp.src(input)
 .pipe(gulpPremailer())
 .pipe(rename("gpremailer.html"))
 .pipe(gulp.dest(output));
 });

 var gPremailer = "gulp gPremailer";

 // DEFAULT TASK
 // ========================================
 gulp.task("default", run([
 gPremailer
 ]));

Контент выше, который делает валидный gulfile.js, запускается через команду gulp:

Необходимо, чтобы были определены все необходимые пакеты для операций, определенных для задач

Обеспечивает настройки (например, файлы и папки ввода/вывода)

Хранит названия задач и выполняемые функции, когда запускается определенная задача

Проверим, запустим команду gulp default в терминале!

Это была настройка нашего проекта. Надеюсь, было понятно. В следующих разделах я покажу, чем инлайн версии отличаются для одного и того же шаблона, а также разберу некоторые настройки для всех инструментов. Я отмечу ключевые различия и особенности реализации, которые необходимо учесть, если вы собираетесь использовать инлайнеры.

Плагины Gulp CSS Inliner

Как в предыдущем шаге, мы запускаем нашу задачу default, а в папке results/ уже появились все файлы. Для сравнения файлов я нашел этот онлайн инструмент, в котором можно визуально инспектировать различия между двумя документами. Прежде чем перейдем к деталям, вы, возможно, хотите проверить рабочие файлы проекта.

Premailer-Gulp-Juice

В этом разделе нашей ссылкой будет пакет premailer-gulp-juice, он хранит медиа запросы в head и инлайнит CSS из классов. Изучив превью, можно увидеть, что они почти идентичны с превью Inlining. Juice добавляет один неожиданный фикс: он завершает теги td атрибутом align=»left».

Заметка: по умолчанию Juice пакет кодирует изображения в Base64, что видно только в пакете-обертке Gulp.

Gulp-Email-Builder

Пакет Gulp-Email-Builder дает много чего, не только инлайн стили: в нем также есть инструменты отправки email и запуска Litmus прямо из файла скрипта. Но эти функции не входят в тему урока, поэтому просто обобщим опции по кастомизации и отличия от пакета Juice.

На что стоит обратить внимание при выборе этого инлайнера:

Пакет позволяет выбирать из нескольких внешних стилей – какие инлайнить, какие вставлять, какие игнорировать. Отличная опция для разработки.

Есть опции по настройке процесса инлайнинга. Например, выбор normalizeWhitespace или decodeEntities доступен во внутреннем пакете cheerio.

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

Litmus превью в этом инструменте можно посмотреть по ссылке.

Gulp-Premailer

Gulp-Premailer очень похож на предыдущий Gulp-Email-Builder. Однако отличие в том, что он инлайнит свойства width из CSS объявлений, а также вставляет медиа запросы и объявления классов ExternalClass. Premailer также предлагает API через NPM. Есть возможность настроить скрипт так, чтобы он посылал HTML и CSS в API, а вы получали инлайн email HTML. У них также есть онлайн инструмент, можете попробовать.

Litmus превью в этом инструменте можно посмотреть по ссылке.

Онлайн CSS инлайнеры

Описанные ниже инструменты способны по-умному брать вставляемые стили из head HTML документа и применять их к тегу body в подходящие HTML элементы, как инлайн стили. Мы разберем, чем они отличаются. Инструменты не всегда работают так как надо. Если не соблюдать правила безопасности, можно получить нежелательные изменения в проекте. Разберем их ниже.

Я протестировал 4 онлайн инлайнера от уважаемых компаний в email маркетинг индустрии. Я использовал сервисы Litmus (Putsmail), Mailchimp, Zurb и Campaing Monitor.

HTML результаты после CSS инлайнинга можно найти в рабочих файлах. (https://github.com/EDMdesigner/html-email-development-tools/tree/master/lesson-08/online-tool-tests)

Эти инструменты имеют сходства, но что еще важнее, у них похожие различия. Я расскажу и объясню, какое нежелательное поведение я обнаружил. Обобщу это ниже:

Использование внешних стилей:

Инструменты Putsmail от Litmus и от Zurb не обрабатывают внешние стили. Инструменты просто не умеют делать этого, поэтому инлайнинг вообще не выполняется. HTML обрабатывается, и к документу применяются предложенные изменения. Если вам нужны внешние стили, лучше выберите онлайн инструменты Mailchimp и Campaign Monitor. Они инлайнят внешние стили, а также в Mailchimp тег link включен, а Campaign Monitor добавляет весь CSS в тег style. То есть дублируются все стили. Но так сохраняются медиа запросы, что сохраняет внешний вид макета.

Использование вставляемых стилей:

Как выяснилось, все инструменты инлайнят многоколоночные значения ширины, заданные в шаблоне. Сначала я подумал, что это проблема, но как показало наше предыдущее исследование на Drop Calc Method (https://blog.edmdesigner.com/the-drop-calc-method-to-create-responsive-html-emails/), эти инлайн стили переписываются из объявлений классов медиа запросов.

Mailchimp и Campaign Monitor сохраняют все вставляемые стили, что: 1 – огромное дублирование кода, 2 – сохраняются умные хаки (как Margin Hack p { Margin: 0px }, рекомендованный Paul Airy) и клиентский таргетинг. Другие инструменты вычеркивают неизвестные CSS классы и свойства.

Последнее, но не менее важное. Стоит отметить отдельные характеристики инструментов:

Zurb удаляет все HTML комментарии, но MSO условные комментарии и меняет HTML doctype на <!DOCTYPE html PUBLIC «-//W3C//DTD XHTML 1.0 Strict//EN» «http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd»><html xmlns=»http://www.w3.org/1999/xhtml»<

Putsmail и Mailchimp удаляют закрывающий тег img, что странно и невалидно по HTML

Campaign Monitor разделяет сокращения padding и margin на их полные формы

Заключение

Мы начали обсуждение с важности CSS инлайнинга для email разработчиков и показали, что в будущем это может быть уже необязательно. Однако инлайнинг все же нужен, когда email клиент требует этого.

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

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

Чтобы еще вас озадачить, скажу, что есть другие техники, обходящие эти ограничения. Используя метод абстрактного описания, вы больше контролируете наиболее важные объявления в макете. Если вы совсем не понимаете, что это, не беспокойтесь. Мы расскажем об этом в следующей статье. Мы поговорим о языках создания шаблонов и шаблонных строках ES2015. Спасибо, что присоединились! Увидимся.

Автор: Mihály Sáróy

Источник: https://blog.edmdesigner.com/

Редакция: Команда webformyself.

Практический курс по верстке адаптивного лендинга с нуля!

Научитесь с нуля верстать адаптивные лендинги на HTML5 и CSS3 за ближайшие 6 дней

Узнать подробнее

Практика HTML5 и CSS3 с нуля до результата!

Получите бесплатный пошаговый видеокурс по основам адаптивной верстки с полного нуля на HTML5 и CSS3

Получить

Метки:

Похожие статьи:

Комментарии Вконтакте:

Комментарии Facebook:

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Можно использовать следующие HTML-теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Я не робот.

Spam Protection by WP-SpamFree