Pull to refresh

Создаём отзывчивые письма для будущего без медиа-запросов

Reading time 26 min
Views 34K
Original author: Nicole Merlin
Создавая HTML код для email, приходится иметь дело с изрядным количеством больных вопросов. И вряд ли для кого то будет приемлемо, если нам к тому же ещё и придётся следить за новыми email-клиентами и размерами устройств, которые появляются каждую неделю. Поддержка media query как и сам CSS разнятся среди приложений, в следствии этого, каждый раз когда вы слышите что появилось новое восхитительное почтовое приложение, для которого тоже нужно провести тесты, вас неизбежно одолевает страх.

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

Приведенный ниже метод, сторонником которого я являюсь, всецело ориентирован на создание положительного опыта взаимодействия при работе с email-клиентами, у которых вообще отсутствует поддержка media query.

Он называется fluid-hybrid method, иногда упоминается как spongy метод для email разработок. Часть fluid предполагает что мы используем изрядной количество процентных вычислений. Часть hybrid означает что мы также используем max-width дабы ограничить некоторые из наших элементов на экранах большего размера.


Шесть главных проблем, которые мы намерены решить


1. Приложение Gmail для Android и iOS — головная боль
Оно более популярно чем дефолтное мейл-приложение для Android, но Gmail не поддерживает media queries, на которые мы традиционно полагаемся при изменении размера и формата на малых экранах. Этот обучающий материал покажет вам как создавать отзывчивые email-сообщения даже в Gmail app.

2. Регулярное появление новых почтовых приложений
Трудно уследить за всеми новыми email приложениями, которые продолжают появляться. Некоторые из них действительно «уделяют внимание» рендерингу сообщений и обладают хорошей поддержкой CSS и media query, но некоторые более сфокусированы на самом потоке обработки писем и вообще не поддерживают media queries. Этот учебный материал покажет как создавать мейлы, которые всегда отзывчивы вне зависимости от степени поддержки CSS.

3. Количество возможных размеров экрана устройства практически неограниченно
У нас есть не только огромные десктопы и крошечные смартфоны, у нас также имеются огромные смартфоны и крошечные лаптопы. Только потому, что кто-то осуществляет доступ к своему Gmail на лаптопе, не означает что его экран достаточно велик для отображения мейла шириной в 700 пикс.; и люди, используя iPhone 6+ могут обработать двухстолбцовую разметку, однако испытывают проблемы с одностолбцовой. Этот обучающий материал покажет вам, как создать разметку, которая меняет формат чтобы соответствовать доступному пространству, даже в webmail.

4. Создание отзывчивых мейлов на мобильных устройствах с помощью расположенных столбцом <td> работает не везде
Определённые email клиенты (для iOS и даже некоторые родные почтовые приложения для предыдущих версий Android) неправильно располагают столбцом две ячейки таблицы в одном ряду; они могут расположить в столбец лишь две отдельные таблицы. В этом обучающем материале используется совершенно другой метод, который полностью поддерживается всеми приложениями и устройствами. Стандартное решение данной проблемы — использование таблиц с атрибутами align="left" или align="right", но это приводит к другой проблеме:

5. Использование метода отзывчивой разработки aligned table приводит к тому, что ваши таблицы упираются влево или вправо в мобильных приложениях, которые не поддерживают media queries
Метод, приведенный в данном учебном материале, использует другой подход, который гарантирует, что все ваши столбцы будут расположены друг над другом по центру на мобильном устройстве, даже в Gmail app (вы также без труда сможете выровнять их по левой или правой стороне по собственному усмотрению).
wrong column alignment
Таблицы, выровненные по левому или правому краю, остаются на своих местах в мобильных приложениях, не поддерживающих media queries. Вы не можете это изменить с помощью мобильного CSS (mobile-specific CSS)

column stack
В этом тьюториале вам будет показано как расположить свои столбцы друг над другом по центру, даже в приложениях, которые не поддерживают media queries

6. Когда вы используете метод отзывчивой разработки aligned table, вы теряете возможность выровнять содержимое по вертикали в столбцах, расположенных рядом
Этот обучающий материал также покажет вам как выровнять два столбца, расположенных в одном ряду, вертикально по верху или по середине так же, как если бы они были ячейками таблицы одного и того же ряда, и которые используют атрибут valign.

table alignment
С помощью этого учебного материала вы освоите метод ’fluid hybrid’, который позволит вам вертикально выравнивать столбцы по верху, середине или низу

1. Давайте приступим


Начните с создания чистого файла, сохраните его как index.html, затем скопируйте и вставьте следующий код:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title></title>
    <link rel="stylesheet" type="text/css" href="styles.css" />
    <!--[if (gte mso 9)|(IE)]>
    <style type="text/css">
        table {border-collapse: collapse;}
    </style>
    <![endif]-->
</head>
<body>
    <center class="wrapper">
        <div class="webkit">
            [content goes here]
        </div>
    </center>
</body>

Давайте быстро пробежимся по всем элементам приведенного выше кода:

!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
это DOCTYPE, который мне нравится больше всех остальных — я убедился что он порождает наименьшее число сюрпризов.

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 
даёт поддержку всех символов Unicode в нашем документе.

<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
используются здесь для того чтобы Windows Phones правильно отображали нашу мобильную версию.

Мы добавим <title></title>, хотя лучше оставить его пустым. Тег title требуется для валидного XHTML, но некоторые родные почтовые клиенты для Android отобразят этот заголовок прямо перед прехедером в inbox превью, это в большинстве случаев не совсем хорошо.

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

Далее, между <!--[if (gte mso 9)|(IE)]> и <![endif]--> у нас имеется условный CSS для Outlook, который принудительно выполнит коллапс границ для всех таблиц и предотвратит появление ненужных пустых мест. Это условное выражение ориентирвано на все версии Microsoft Outlook (mso) начиная с 9ой версии и выше (это, по сути, все версии, т. к. 9я и самая ранняя — это Outlook 2000), также как и на те версии, которые использую Interner Explorer для рендера (Outlook 2000-2003).

Сразу же после body у нас расположен тег <center>, чтобы отцентрировать содержимое и выполнить роль носителя нескольких полезных CSS свойств (поскольку тег body частенько очищается в клиентах webmail). У нас также имеется <div class="webkit"> для более ранних версий почтовых клиентов, построенных на Webkit (в основном Apple Mail 6 и ниже, а также Outlook 2011 в некоторых случаях). Эти ранние версии поддерживают max-width только для блочных элементов и наиболее простой способ заставить нашу вёрстку отображаться в правильном размере — обернуть её в этот div, что позволит нам обойтись без установки ширины в media query, как в моём предыдущем тьюториале (благодарите zerocents за этот фикс).

2. Начальные стили


Далее, создайте чистый CSS файл с названием styles.css Вставьте следующее в только что созданный файл:
/* Basics */
body {
    Margin: 0;
    padding: 0;
    min-width: 100%;
    background-color: #ffffff;
}
table {
    border-spacing: 0;
    font-family: sans-serif;
    color: #333333;
}
td {
    padding: 0;
}
img {
    border: 0;
}
.wrapper {
    width: 100%;
    table-layout: fixed;
    -webkit-text-size-adjust: 100%;
    -ms-text-size-adjust: 100%;
}
.webkit {
    max-width: 600px;
}
 
/* Windows Phone Viewport Fix */
@-ms-viewport { 
    width: device-width; 
}

Здесь я обнуляю margin и padding для body, таблицы и табличных ячеек, а также обнуляю всякие границы, которые могут появиться вокруг изображений по ссылкам. Наши стили для тегов table и td нужны в качестве замены HTML атрибутов cellpadding и cellspacing. Вы вправе выбрать HTML атрибуты как альтернативу, если желаете; в прошлом я всегда поддерживал выбор HTML атрибутов вместо CSS свойств там где это было возможно, однако, по мере того как я работал над более и более масштабируемыми проектами, я обнаружил что могу достичь большей управляемости, размещая это в CSS, в особенности если вы, как правило, работаете в платформе, которая автоматически обрабатывает CSS инлайнинг.

Также я обычно добавляю min-width со значением в 100% тегу <body>, дабы избежать всяких ситуаций когда контент не занимает полную ширину вьюпорта на мобильном устройстве, также всегда хорошей идеей будет задать цвет для background, даже если он абсолютно белый, дабы избежать цветовых глюков background в Outlook или Lotus Notes.

У нас также имеются свои стили с несколькими свойствами для .wrapper, которые препятствуют странному изменению размера текста на Windows Phones и iOS, вместе с этим table-layout: fixed будет гарантировать, что наш отцентрированный контент также будет отцентрирован в Yahoo mail. Мы устанавливаем max-width шириной в 600px для нашего .webkit div для ограничения содержимого в Apple Mail 6 (и ниже) и Outlook 2011.

И наконец, у нас имеется фикс для вьюпорта, который вместе с двумя нашими метатегами в заголовке, будет гарантировать беспроблемное отображение на Windows Phones.

3. Создание внешнего структурного контейнера


Начнём с одного из ключевых строительных блоков в данном методе: условной таблицы (conditional table) для Outlook, которая является скрытой для всех остальных клиентов. Нам это необходимо, т. к. мы собираемся использовать свойство max-width, которое Outlook не поддерживает. Поэтому нам необходимо создать специальные Outlook-only таблицы с явно заданной пиксельной шириной, которые будут всё вмещать.

Outlook table
Применяется наша условная таблица для Outlook, т. к. Outlook не поддерживает свойство max-width

Итак, давайте удалим заполнитель [content goes here] из нашего HTML файла и вставим следующий код. Я стараюсь выравнивать все теги условного кода (conditional code) по левому краю и соблюдать равный уровень отступа для читабельности, но вы можете выравнивать их по собственному усмотрению.
<!--[if (gte mso 9)|(IE)]>
<table width="600" align="center">
<tr>
<td>
<![endif]-->
<table class="outer" align="center">
    <tr>
        <td>
            [content goes here]
        </td>
    </tr>
</table>
<!--[if (gte mso 9)|(IE)]>
</td>
</tr>
</table>
<![endif]-->

Примечание: для тегов условной таблицы стили отсутствуют. Я намерен применить инструмент для инлайнинга от Campaign Monitor inliner.cm, он также выполняет инлайнинг стилей и для условных таблиц. Если вы собираетесь использовать другой инлайнер, то он может этого не сделать, поэтому удостоверьтесь что cellpadding="0" cellspacing="0" border="0" добавлены в условную таблицу Outlook.

Внутри нашей условной таблицы вы увидите что у нас имеется <table class="outer"> — это наш ключевой внешний строительный блок для всех клиентов кроме Outlook.

Мы хотим, чтобы эта внешняя таблица имела ширину в 100% на малых кранах, а на экранах большего размера — не более 600px. Поэтому мы намерены установить её width в 100% и задать ей max-width в 600px

outer table

Для нашей таблицы установлена ширина в 100%, пока она не достигнет 600px

Полезный совет: для быстрой и простой буферизации на мобильном устройстве без заморочек с паддингами и media queries измените ширину своей таблицы со 100% до 95%

Итак, давайте поместим эти стили в наш styles.css:
.outer {
    Margin: 0 auto;
    width: 100%;
    max-width: 600px;
}

У нас здесь также есть Margin: 0 auto; чтобы отцентрировать нашу таблицу в Yahoo при просмотре в Chrome. margin, однако, применяется здесь только ради Yahoo, я всегда пишу Margin с большой буквы чтобы Outlook.com его не чистил — маленький изящный хак, спасибо Wiktor за комментарий в этом блогпосте.

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

4. Добавление баннерного изображения в полную ширину


Сперва скачайте файлы обучающего материала и переместите папку /images в папку с index.html

Теперь давайте добавим класс full-width-image к td внутри нашей таблицы .outer, потом мы заменим наш заполнитель [content goes here] на тег image, таким образом наша таблица примет следующий вид:
<table class="outer" align="center">
    <tr>
        <td class="full-width-image">
            <img src="images/header.jpg" alt="" />
        </td>
    </tr>
</table>

Вы обратите внимание, что я не побеспокоился об атрибутах width или height для изображения. Я собираюсь решить это с помощью CSS, который мы добавим, и он будет выглядеть следующим образом:
.full-width-image img {
    width: 100%;
    height: auto;
}

Это подводит нас к одному весьма важному нюансу в этом методе, который касается изображений.

Изображения всегда должны выводиться в размерах, соответствующих по физическим пикселям


Этот метод всецело ориентирован на использование процентов дабы всё было подвижно и выглядело хорошо. Следовательно, нам практически всегда нужно, чтобы ширина наших изображений была установлена в 100% от своих контейнеров. Если мы хотим осуществить это, то должны помещать наши изображения, в размере, который соответствует по физическим пикселям. По той причине, что Outlook 2007, 2010 и 2013 не будут масштабировать (в большую или меньшую сторону) изображения по отношению к их физическим размерам, до тех пор пока вы явно не зададите пиксельную ширину оного. Если бы вы разместили изображение шириной в 1200px в ячейке шириной 600px и задали ему ширину в 100%, то Outlook вывел бы его шириной в 1200px. Поэтому, если у вас ячейка шириной в 600px (на декстопе), то вам необходимо применять изображение шириной в 600px.

Чтобы решить проблему с изображениями, размер которых менее поддерживаемой ширины экрана, вы можете явно задать им пиксельную ширину (например, 100px) и использовать изображения высокого разрешения, т. к. в приложениях без media-query их ширина всегда будет 100px что прекрасно смотрится в любом мобильном вьюпорте. Однако, если бы у вас был столбец шириной в 350px, то вы бы не смогли задать изображению ширину в 350px, поскольку, если бы вам пришлось вывести это изображение в Gmail app на вьюпорте шириной в 320px, то оно бы было слишком широким.

Часто необходимо удостоверится, что ширина всех изображений задана в 100%, даже если они у́же самого маленького мобильного вьюпорта, т. к. это даёт вам больше гибкости при добавлении прогрессивного улучшения в виде media query.

Моё практическое правило — всякое изображение должно выводиться в соответствующем по физическим пикселям размере, если только это не иконка шириной менее 100px

Итак, принимая это всё во внимание, мы сохранили изображение с именем header.jpg, шириной именно в 600px и разместили его в нашей директории images. Позаимствуйте его или сохраните своё собственное и теперь вы можете выполнить предпросмотр HTML файла и увидеть как изображение гибко меняет размер в зависимости от размера вьюпорта.

5. Добавление одностолбцового макета


Добавьте ещё одну строку в таблицу .outer с помощью следующей разметки:
<tr>
    <td class="one-column">
        <table width="100%">
            <tr>
                <td class="inner contents">
                    <p class="h1">Lorem ipsum dolor sit amet</p>
                    <p>Maecenas sed ante pellentesque, posuere leo id, eleifend dolor. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Praesent laoreet malesuada cursus. Maecenas scelerisque congue eros eu posuere. Praesent in felis ut velit pretium lobortis rhoncus ut erat.</p>
                </td>
            </tr>
        </table>
    </td>
</tr>

И добавьте следующие стили в styles.css:
.inner {
    padding: 10px;
}
p {
    Margin: 0;
}
a {
    color: #ee6a56;
    text-decoration: underline;
}
.h1 {
    font-size: 21px;
    font-weight: bold;
    Margin-bottom: 18px;
}
.h2 {
    font-size: 18px;
    font-weight: bold;
    Margin-bottom: 12px;
}
 
/* One column layout */
.one-column .contents {
    text-align: left;
}
.one-column p {
    font-size: 14px;
    Margin-bottom: 10px;
}

Вы обратите внимание, что я использовал теги <p> и набор классов для их стилизации. Мне нравится применять абзацы для стилизации текста и вы можете легко ими управлять благодаря хаку с большой М в Margin, о котором я упоминал ранее. Я также применяю <p class="h1"> вместо <h1>, т. к. у Outlook.com есть кое-какие стили для h1, h2 и h3, которые всегда перекрывают ваши стили.

Таким образом в указанном выше CSS мы установили 10px padding для нашего столбца, сбросили margin для <p>, установили некоторые базовые стили для ссылок и моих классов .h1 и .h2, а затем обеспечили выравнивание по левому краю в стилизированных абзацах для нашего столбца.

Теперь перейдём к увлекательному этапу… множеству столбцов!

6. Добавление двухстолбцового макета*


*который будет отцентрирован при вертикальном складывании

2-column layout

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

Сперва добавьте новую строку в таблицу .outer. Она содержит ячейку с классом .two-column, а внутри неё — условную таблицу для Outlook с двумя столбцами шириной в 50%:
<tr>
    <td class="two-column">
        <!--[if (gte mso 9)|(IE)]>
        <table width="100%">
        <tr>
        <td width="50%" valign="top">
        <![endif]-->
        [column to go here]
        <!--[if (gte mso 9)|(IE)]>
        </td><td width="50%" valign="top">
        <![endif]-->
        [column to go here]
        <!--[if (gte mso 9)|(IE)]>
        </td>
        </tr>
        </table>
        <![endif]-->
    </td>
</tr>

Эти условные столбцы важны, поскольку без них Outlook не позволит двум нашим плавающим таблицам расположиться аккуратно рядышком. Поскольку Outlook к тому же не поддерживает max-width, эти столбцы помогают удерживать каждый столбец (прим. пер. имеется ввиду дочернее содержимое) в нужном размере.

Outlook 2 cells
Визуализация того, что будет представлять из себя наша двухстолбцовая структура

Теперь замените каждый заполнитель [column to go here] следующим:
<div class="column">
    <table width="100%">
        <tr>
            <td class="inner">
                [content goes here]
            </td>
        </tr>
    </table>
</div>

Способ с помощью которого мы намерены заставить два столбца плавать (параллельно) рядом на десктопе, но складываться вертикально по центру на мобильном устройстве, состоит в использовании комбинации text-align: center и display: inline-block. Все инлайновые и инлайн-блочные элементы подчиняются свойству text-align. Поэтому, если мы обернём наши таблицы в div с установленным inline-block, то мы сможем довольно просто задать их выравнивание (alignment), когда они расположены друг над другом — установкой свойства text-align для их контейнера. Вы можете выбрать выравнивание по левому краю, центру или правому краю и ваши инлайн-блочные divы будут «слушаться». И вы действительно сможете задать самой таблице display: inline-block, но только если не собираетесь размещать внутри неё какие-либо другие таблицы. Всё начинает вести себя дико, если вы вкладываете таблицы внутрь inline-block таблиц, поэтому, если вам необходимо что-то вложить, убедитесь что инлайн-блочным контейнером является div.

Давайте добавим нашей контейнерной ячейке стиль .two-column с выбранным нами выравниванием. Мы также собираемся добавить font-size: 0 чтобы избавиться от пустых пространств между нашими столбцами внутри этой ячейки.
/*Two column layout*/
.two-column {
    text-align: center;
    font-size: 0;
}

Теперь мы зададим стиль нашему инлайн-блочному div, который ведёт себя как столбец:
.two-column .column {
    width: 100%;
    max-width: 300px;
    display: inline-block;
    vertical-align: top;
}

Мы используем ширину в 100% с максимальной шириной до 300px, таким образом, именно у этого столбца на вьюпортах с шириной менее 300px, будет 100% ширина.

Вы можете задать своему vertical-align что угодно: top, center или bottom. [примечание переводчика: здесь, очевидно, ошибка — разве у vertical-align существует свойство center?] Значение top для vertical-align задаёт поведение при котором каждый столбец ведёт себя сродни табличной ячейки с HTML-свойством valign="top", соответственно middle даёт эффект подобный valign="middle". Обратите внимание, что у вас может быть множество строк из этих div внутри одной ячейки и вертикальное выравнивание всегда будет следовать принципу ряда за рядом. Это замечательно! Также удостоверьтесь, что выбор, который вы совершили здесь, совпадает с valign, который вы установили для условной таблицы Outlook, т. к. Outlook не поддерживает vertical-align. Если у вас выравнивание в Outlook не соответствует ожидаемому, то распространённой причиной может быть отсутствие заданного значения valign для условной таблицы.

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

Итак, давайте заменим наши два заполнителя [content goes here] следующим:
<table class="contents">
    <tr>
        <td>
            <img src="images/two-column-01.jpg" alt="" />
        </td>
    </tr>
    <tr>
        <td class="text">
            Maecenas sed ante pellentesque, posuere leo id, eleifend dolor. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. 
        </td>
    </tr>
</table>

Здесь ширина наших изображений составляет 280px. Согласно тому, что обсуждалось выше, оно было сохранено в точных пиксельных размерах, чтобы соответствовать ячейке, в которую мы будем его размещать. Ширина каждого столбца составляет 300px с 10px паддингами на каждой стороне, что оставляет 280px для изображения.

Далее мы зададим стиль для класса .contents, установив ему ширину в 100%:
.contents {
    width: 100%;
}


А затем давайте добавим наш стайлинг двухстолбцовому макету, чтобы задать размер нашего шрифта и выравнивание текста, обеспечить вывод изображений на 100% ширину и установить немного паддинга для нашего тексту снизу:
.two-column .contents {
    font-size: 14px;
    text-align: left;
}
.two-column img {
    width: 100%;
    height: auto;
}
.two-column .text {
    padding-top: 10px;
}

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

7. Добавление трёхстолбцового макета


И снова мы намерены создать расположенные рядом (бок о бок) столбцы, которые складываются вертикально на мобильном устройстве, с помощью комбинации text-align: center и display: inline-block.

Мы собираемся использовать text-align: center чтобы наши столбцы складывались по центру, но вы также можете применить выравнивание по левому или правому краю. Вот пример того, как складываются элементы при выравнивании по центру и по левому краю:

3-column center alignment
пример того, как будут сложены 3 столбца при задании контейнеру text-align: center

3-coulmn left alignment
пример того, как будут сложены 3 столбца при задании контейнеру text-align: left

Итак, мы повторим двухстолбцовый процесс, с добавлением дополнительного. Добавьте данный новый ряд в таблицу .outer. (Я обычно предпочитаю использовать процентную ширину для ячеек в условных таблицах Outlook, но в данном случае будет проще задать для каждой ширину в 200).
<tr>
    <td class="three-column">
        <!--[if (gte mso 9)|(IE)]>
        <table width="100%">
        <tr>
        <td width="200" valign="top">
        <![endif]-->
        [column to go here]
        <!--[if (gte mso 9)|(IE)]>
        </td><td width="200" valign="top">
        <![endif]-->
        [column to go here]
        <!--[if (gte mso 9)|(IE)]>
        </td><td width="200" valign="top">
        <![endif]-->
        [column to go here]
        <!--[if (gte mso 9)|(IE)]>
        </td>
        </tr>
        </table>
        <![endif]-->
    </td>
</tr>

Теперь добавьте следующий CSS, чтобы задать дополнительный padding этому ряду и чтобы установить все свойства, которые мы использовали в двухстолбцовом макете, дабы заставить наши столбцы вести себя так, как нам это необходимо. Он также задаст стили для наших div столбцов, которые мы вскоре добавим, и ширина которых в данном случае будет составлять 200px.
/*Three column layout*/
.three-column {
    text-align: center;
    font-size: 0;
    padding-top: 10px;
    padding-bottom: 10px;
}
.three-column .column {
    width: 100%;
    max-width: 200px;
    display: inline-block;
    vertical-align: top;
}
.three-column .contents {
    font-size: 14px;
    text-align: center;
}
.three-column img {
    width: 100%;
    height: auto;
}
.three-column .text {
    padding-top: 10px;
}

Давайте вставим наши столбцы, меняя каждый из заместителей [column to go here] на таблицу:
<table class="column">
    <tr>
        <td class="inner">
            <table class="contents">
                <tr>
                    <td>
                        <img src="images/three-column-01.jpg" alt="" />
                    </td>
                </tr>
                <tr>
                    <td class="text">
                        Scelerisque congue eros eu posuere. Praesent in felis ut velit pretium lobortis rhoncus ut erat. 
                    </td>
                </tr>
            </table>
        </td>
    </tr>
</table>

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

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

Добавление трёхстолбцового макета с множеством рядов


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

column reflow

И хотя вам нет нужды разделять ряды из divов для большинства клиентов, вам определённо необоходимо добавить дополнительные <tr> к своей условной таблице для Outlook.

Outlook cinditional tables with row/columns separation

Вот как работает наша условная таблица для Outlook, разделяя наши ряды и столбцы

Давайте испытаем это, добавив новый ряд с классом .three-column в таблицу .outer. Вот у нас ряд из трёх столбцов с условной таблицей внутри. Вы увидите, что в нашей таблице имеются три столбца и мы звершаем ряд условной таблицы с помощью </tr> и открываем новый <tr>, который содержит 3 другие ячейки шириной в 200px.

<tr>
    <td class="three-column">
        <!--[if (gte mso 9)|(IE)]>
        <table width="100%">
        <tr>
        <td width="200" valign="top">
        <![endif]-->
        [column to go here]
        <!--[if (gte mso 9)|(IE)]>
        </td><td width="200" valign="top">
        <![endif]-->
        [column to go here]
        <!--[if (gte mso 9)|(IE)]>
        </td><td width="200" valign="top">
        <![endif]-->
        [column to go here]
        <!--[if (gte mso 9)|(IE)]>
        </td>
        </tr>
        <tr>
        <td width="200" valign="top">
        <![endif]-->
        [column to go here]
        <!--[if (gte mso 9)|(IE)]>
        </td><td width="200" valign="top">
        <![endif]-->
        [column to go here]
        <!--[if (gte mso 9)|(IE)]>
        </td><td width="200" valign="top">
        <![endif]-->
        [column to go here]
        <!--[if (gte mso 9)|(IE)]>
        </td>
        </tr>
        </table>
        <![endif]-->
    </td>
</tr>

Далее, мы добавляем таблицу подобную следующей, каждой условной ячейке, убирая заместитель [column to go here]:
<table class="column">
    <tr>
        <td class="inner contents">
            <p class="h2">Heading</p>
            <p>Class eleifend aptent taciti sociosqu ad litora torquent conubia</p>
            <p><a href="#">Read more</a></p>
        </td>
    </tr>
</table>

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

Добавление ещё большего количества столбцов


Мы больше не будем добавлять многостолбцовые макеты в данном учебном материале, но в вашем макете может быть столько столбцов, сколько угодно. Всё, что вам необходимо сделать — удостовериться, что все ваши блоки с контентом соответствуют ширине вашего контейнера, и что ваша условная таблица для Outlook содержит подходящее количество ячеек и рядов для вмещения оных.

Добавление двухстолбцового макета с 'Sidebar'


Далее мы создадим двухстолбцовый макет с шириной столбца в 500px, а затем более узкую боковую панель шириной в 100px для иконки.

Сперва мы создадим ряд и ячейку с классом .left-sidebar, а внутри неё поместим условную таблицу для Outlook, в которой присутствует один ряд и два неравных столбца:
<tr>
    <td class="left-sidebar">
        <!--[if (gte mso 9)|(IE)]>
        <table width="100%">
        <tr>
        <td width="100">
        <![endif]-->
        [column to go here]
        <!--[if (gte mso 9)|(IE)]>
        </td><td width="500">
        <![endif]-->
        [column to go here]
        <!--[if (gte mso 9)|(IE)]>
        </td>
        </tr>
        </table>
        <![endif]-->
    </td>
</tr>

Затем, в каждом столбце, убирая заместитель [column to go here], мы добавим таблицу. В этот раз один из них мы назовём .column .left, а другой — .column .right, т. к. у них разная ширина.

Примечание: здесь я использую множество классов для одного элемента. Некоторые инструменты для инлайнинга и/или ESP могут этого не поддерживать, поэтому, сперва выполните проверку с помощью своей системы или платформы. Как было сказано выше, я использую inliner.cm для инлайнинга своего CSS, который точно поддерживает множество классов.

Добавьте левую таблицу в первый столбец, который содержит нашу иконку:
<table class="column left">
    <tr>
        <td class="inner">
            <img src="images/sidebar-01.jpg" width="80" height="80" alt="" />
        </td>
    </tr>
</table>

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

Затем, добавьте правую таблицу, которая содержит текст и ссылку, во второй столбец:
<table class="column right">
    <tr>
        <td class="inner contents">
            Praesent laoreet malesuada cursus. Maecenas scelerisque congue eros eu posuere. Praesent in felis ut velit pretium lobortis rhoncus ut erat. <a href="#">Read on</a>
        </td>
    </tr>
</table>

Эти таблицы весьма просты и внутри них ничего не вложено, поэтому, вместо того чтобы оборачивать их в div, я собираюсь задать display: inline-block для самих таблиц, чтобы сократить разметку. Как обсуждалось выше, станете ли вы вкладывать внутрь большее количество элементов — всего лишь вопрос практичности. Если вы будете реализовывать большое количество вложенностей, оберните эту таблицу в div и задайте ему класс .column .right

Далее, давайте зададим стили контейнеру и установим столбцы:
/* Left sidebar layout */
.left-sidebar {
    text-align: center;
    font-size: 0;
}
.left-sidebar .column {
    width: 100%;
    display: inline-block;
    vertical-align: middle;
}
.left-sidebar .left {
    max-width: 100px;
}
.left-sidebar .right {
    max-width: 500px;
}

И, наконец, давайте зададим стили текста и цвет ссылки:
.left-sidebar .contents {
    font-size: 14px;
    text-align: center;
}
.left-sidebar a {
    color: #85ab70;
}

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

9. Добавление макета с обратным 'Sidebar'


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

Сначала мы намерены скопировать и вставить весь наш ряд с ячейкой .left-sidebar, и единственное что мы будем менять — это класс контейнерной ячейки, с .left-sidebar на .right-sidebar:
<tr>
    <td class="right-sidebar">
        <!--[if (gte mso 9)|(IE)]>
        <table width="100%">
        <tr>
        <td width="100">
        <![endif]-->
        <table class="column left">
            <tr>
                <td class="inner contents">
                    <img src="images/sidebar-02.jpg" width="80" height="80" alt="" />
                </td>
            </tr>
        </table>
        <!--[if (gte mso 9)|(IE)]>
        </td><td width="500">
        <![endif]-->
        <table class="column right">
            <tr>
                <td class="inner contents">
                    Maecenas sed ante pellentesque, posuere leo id, eleifend dolor. Class aptent taciti sociosqu ad litora torquent per conubia nostra. <a href="#">Per inceptos</a>
                </td>
            </tr>
        </table>
        <!--[if (gte mso 9)|(IE)]>
        </td>
        </tr>
        </table>
        <![endif]-->
    </td>
</tr>

Всё остальное остаётся в прежнем виде.

Мы собираемся сделать следующее: обратить dir="rtl" (это означает направление справа налево) себе в преимущество. Это свойство предназначено для обозначения алфавитов, которые размещаются справа налево, таких как арабский. Но в нашем случае оно просто будет указывать каждому почтовому клиенту, что наши элементы нужно выводить в обратном порядке.

dir='rtl' causes stacking in opposite order

Наши элементы будут выводиться в обратном порядке, если для их контейнера установлен dir="rtl"

Сперва, вам необходимо добавить dir="rtl" для контейнера (.right-sidebar). Это указывает, что наши плавающие таблицы нужно выводить справа налево. Таким образом, наш открывающий тег теперь должен принять следующий вид:
<td class="right-sidebar" dir="rtl"> 

Затем, в условном коде для Outlook нам также необходимо добавить dir="rtl" для <table>, т. к. мы указываем таблице, что <td> нужно выводить в обратном порядке.

Итак, наш открывающий условный комментарий должен сейчас выглядеть следующим образом:
<!--[if (gte mso 9)|(IE)]>
<table width="100%" dir="rtl">
<tr>
<td width="100">
<![endif]-->

И, наконец, нам необходимо добавить dir="ltr" к нашим таблицам .column-left и .column-right, поскольку внутри них находится контент и, поскольку он на английском, его необходимо направлять слева направо. Если мы не установим это значение для данных элементов, они унаследуют направление справа налево от своих родительских элементов.

Наш .column-left теперь должен выглядеть следующим образом:
<table class="column left" dir="ltr">
    <tr>
        <td class="inner contents">
            <img src="images/sidebar-02.jpg" width="80" height="80" alt="" />
        </td>
    </tr>
</table>

А наш .column-right сейчас должен выглядеть так:
<table class="column right" dir="ltr">
    <tr>
        <td class="inner contents">
            Maecenas sed ante pellentesque, posuere leo id, eleifend dolor. Class aptent taciti sociosqu ad litora torquent per conubia nostra. <a href="#">Per inceptos</a>
        </td>
    </tr>
</table>

Таким образом, в итоге, весь наш ряд теперь должен принять следующий вид:
<tr>
    <td class="right-sidebar" dir="rtl">
        <!--[if (gte mso 9)|(IE)]>
        <table width="100%" dir="rtl">
        <tr>
        <td width="100">
        <![endif]-->
        <table class="column left" dir="ltr">
            <tr>
                <td class="inner contents">
                    <img src="images/sidebar-02.jpg" width="80" height="80" alt="" />
                </td>
            </tr>
        </table>
        <!--[if (gte mso 9)|(IE)]>
        </td><td width="500">
        <![endif]-->
        <table class="column right" dir="ltr">
            <tr>
                <td class="inner contents">
                    Maecenas sed ante pellentesque, posuere leo id, eleifend dolor. Class aptent taciti sociosqu ad litora torquent per conubia nostra. <a href="#">Per inceptos</a>
                </td>
            </tr>
        </table>
        <!--[if (gte mso 9)|(IE)]>
        </td>
        </tr>
        </table>
        <![endif]-->
    </td>
</tr>

И, наконец, давайте добавим наших стилей, которые полностью идентичны .left-sidebar за исключением ссылки.
/* Right sidebar layout */
.right-sidebar {
    text-align: center;
    font-size: 0;
}
.right-sidebar .column {
    width: 100%;
    display: inline-block;
    vertical-align: middle;
}
.right-sidebar .left {
    max-width: 100px;
}
.right-sidebar .right {
    max-width: 500px;
}
.right-sidebar .contents {
    font-size: 14px;
    text-align: center;
}
.right-sidebar a {
    color: #70bbd9;
}

Славно! Теперь у нас есть две панели на противоположных сторонах, но когда всё выстраивается в столбец на мобильном устройстве обе боковые панели выводятся над текстом.

10. Добавление прогрессивного улучшения с помощью Media Queries


Теперь у вас есть завершённый почтовый шаблон, отзывчивый везде без единого media query! Но, конечно же, существует совсем немного почтовых клиентов, которым действительно нужна поддержка media queries, теперь, при помощи нескольких твиков, мы можем заняться прогрессивным улучшением нашего (и без того замечательного) шаблона, дабы всё выглядело красиво в таких клиентах как iOS Mail.

Сначала мы заставим наши столбцы выводиться на 100% ширины всякого вьюпорта с шириной до 400px. Мы также ограничим ширину наших трёхстолбцовых изображений до 50%, чтобы они не принимали слишком большой размер. Всё, что нам необходимо сделать — сбросить max-width этих столбцов, поскольку, как вы помните, у них у всех и так уже 100% ширина и их ограничивает лишь max-width.

Итак, добавьте следующее в свой CSS файл:
/*Media Queries*/
@media screen and (max-width: 400px) {
    .two-column .column,
    .three-column .column {
        max-width: 100% !important;
    }
    .three-column img {
        max-width: 50% !important;
    }
}

Затем, для ширины между 401px и 600px, мы добавим следующее, чтобы двух и трёхстолбцовые макеты выводились как на декстопе, но при этом сжимались до подходящего размера.
@media screen and (min-width: 401px) and (max-width: 620px) {
    .three-column .column {
        max-width: 33% !important;
    }
    .two-column .column {
        max-width: 50% !important;
    }
}

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

11. Инлайнинг вашего кода


Наконец, если вам нужно выполнить инлайнинг вашего кода, возьмите содержимое style.css и поместите его в <head> своего документа index.html между тегами <style type="text/css"> и </style>. Затем, скопируйте и вставьте содержимое всего файла в рабочую область inliner.cm и дождитесь результатов. Как только закончится обработка, скопируйте содержимое рабочей области и можете начинать!

И вот вы достигли результата!


Отличная работа! Теперь у нас есть полноценный отзывчивый HTML email в котором менее 20 линий media queries.

Несколько советов и примечаний напоследок

  • Я решил, что ключевыми особенностями данного метода разработки email являются простота и единообразие. Всё начинает выходить из под контроля, когда у вас разный padding для разных столбцов. Вы обратите внимание, что в данном учебном материале я везде выдерживал padding в 10px для класса .inner, который применяется к каждому отдельному макету. Это важно, т. к. вам необходимо чтобы padding был однородным при вертикальном построении на мобильном устройстве.
    the padding uniformity
    Всегда выдерживайте равную величину padding по левой и правой стороне своих элементов, т. о. на мобильных клиентах без поддержки media query паддинг будет однородным

  • Иногда вам может понадобиться проводить расчёты, продвигаясь вовне, чтобы определить какой будет ширина вашей разметки, в зависимости от наилучшего постоянного значения padding, вместо того, чтобы исходить из внешней ширины, а затем продолжать свою работу во внутреннем направлении.
  • Проектирование в браузере всегда будет хорошим подходом, поскольку нередко бывает очень отрудно адаптировать определённые проекты к работе с такой методикой.
  • При использовании этого метода можно вполне спокойно начинать проектировать email, которые гораздо шире обычных, поскольку вы знаете, что шаблон перестроит себя, чтобы помещаться в малые вьюпорты, даже в вебмейл. Единственным подводным камнем является Outlook, которому всё ещё необходимы условные таблицы, чтобы всё выглядело замечательно, поэтому пользователи Outlook всегда будут видеть всё сообщение в наибольшей ширине. Даже не смотря на это, вам всё ещё нужно держать этот наименьший общий знаменать в уме, за пределами стандартных ограничений для email в 500-600px, которые мы обычно устанавливаем, ещё определённо имеется некоторое пространтво куда можно передвинуться.
  • И, наконец, всегда проверяйте, что вы помещаете изображения в соответствующих по физическим пикселям размерах. Хорошим способом удостовериться, что вы всегда соблюдаете это правило, является создание кода для макета с последующим применением инспектора из браузерных инструментов для определения реальной величины финального пространства. Затем вы сможете убедиться, что ваше изображение создано именно с такими размерами. Не забывайте ещё раз проверить это в конце, просто чтобы убедиться что всё нормально. Если вы этого не сделаете, то Outlook любезно укажет вам на ошибку в ваших методиках, т. к. он выведет каждое отдельное изображение в его физических размерах.

Иконки

Ещё раз спасибо Пьеру Бородину за все иконки, которые испольозовались в моём учебном материале.
Tags:
Hubs:
+15
Comments 7
Comments Comments 7

Articles