В нашем блоге мы неоднократно затрагивали тему создания адаптивных почтовых рассылок. В наши дни почти половина всех писем просматривается со смартфонов и планшетов, а значит, необходимо позаботиться о том, чтобы письмо хорошо выглядело на устройствах с разным форм-фактором. Именно для этого в вёрстке и начали использовать медиазапросов (media queries). Однако существует целый ряд препятствий для широкого применения технологии. Сегодня мы по-дробнее взглянем на проблемы при использовании media queries и их возможные решения.

Зачем нужны медиазапросы в email


Для начало еще раз остановимся на то, что собой представляют медиазапросы. Итак, media query — это компонент языка CSS. Этот компонент часто используется в качестве «переключателя», который на основе набора правила отвечает за выбор тех или иных стилей оформления.

Media query состоит из трех частей: тип среды (‘media’), выражение (‘expression’) и правила стилей, которые содержатся в самой media query.



Media type используется для объявления среды, к которой будут применяться правила. Существует четыре вариант: все, печать, экран, речь(all, print, screen и speech). Для задач email почти всегда используется тип screen.

Выражения (expressions) позволяют таргетировать устройства с помощью более узких условий. Выражения описывают свойства устройства, например ширину (witdh) и высоту экрана, соотношение сторон (aspect-ratio) и цвет. Часто дизайнеры используют следующие свойства:

  • max- и min-width;
  • max- и min-device-width;
  • device-pixel-ratio.

И, наконец, в фигурных скобках указываются CSS-правила, которые применяются, если письмо открывается на устройстве, соответствующем требованиям по типу среды и свойствам в выражении. Media queries пишутся в блоке стилей, который как правило расположен в заголовке html-шаблона.

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

В чем проблема


Главный минус всей этой ситуации — media queries работают далеко не везде. Например, один из популярнейших в мире почтовых клиентов Gmail ни в браузере ни в мобильных приложениях не поддерживает эту технологию — почтовая программа просто отрезает секцию шаблона с <head>, где как раз и располагаются все стили и media queries.
Поддержка Media Query почтовыми клиентами
iOS (iPhone/iPad)
check-green
Gmail app (iOS + Android)
check-x
Inbox by Gmail app (iOS + Android)
check-x
Android 4.x native client
check-green
Android Outlook Exchange via native client
check-x
Android Outlook.com app
check-green
Android Yahoo! Mail app
check-X
Gmail (Android Browser)
check-X
Mailbox (iOS + Android)
check-x
Outlook.com (Android Browser)
check-X
Outlook.com (iOS)
check-green
Yahoo! Mail (Android Browser)
check-X
Windows Phone 7
check-X
Windows Phone 7.5
check-green
Windows Phone 8
check-X
BlackBerry OS 6
check-green
BlackBerry OS 7
check-green
BlackBerry Z10
check-green
Kindle Fire native client
check-green

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

Именно проблемы с поддержкой media queries влечет за собой необходимость создания шаблонов рассылок с помощью HTML и инлайн-стилей и использовании media queries только в качестве «приправы», позволяющей прогрессивно улучшать дизайн.

Как реализовать адаптивность в Gmail


Профессионалы в области email-рассылок, конечно же, не могли так просто смириться с невозможностью создания интерактивных и адаптивных писем в Gmail. Один из них — автор блога Freshinbox Джастин Ку, реализовал интересный способ реализации этой функции.

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



Если при создании письма используется заданная максимальная ширина в 600 пикселей, то первую «точку прерывания» (breakpoint) можно было бы установить именно на этой отметке, однако Gmail учитывает ширину окна браузера, а не контейнера email-сообщения, как делают некоторые другие почтовые программы.
В таком случае, первый медиазапрос можно использовать на отметке в 1160 пикселей — при этом ширина email-контейнера составит как раз 600 пикселей.

@media screen and (max-width:1160px){
		* [lang=x-outer]{
			width:100% !important;
		}
	}

Когда окно браузера будет сужено до 700px, то ширина области письма составит уже всего 450px. Если ширина будет еще меньше, появится горизонтальный скролл, который является не самым удобным элементом навигации.

Чтобы этого избежать, нужно установить ширину на отметке в 100% ширины экрана минус 250 пикселей для колонки, зафиксированной в левой части экрана.

@media screen and (max-width:700px){
		* [lang=x-outer]{
			width:calc(100vw - 250px) !important;
			float:left;
		}
	}

Здесь используются единицы измерения vw1 vw = 1% viewport width (в данном случае, окна браузера). При этом процентами описывается размер элемента, содержащегося в контейнере (в нашем случае, зафиксированном на 450px). Затем для осуществления подсчетов используется функция Calc (умеет работать с величинами px, %, em, rem, vw, vh и т.п.)

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

@media screen and (max-width:550px){
		* [lang=x-outer]{
			width:300px !important;
		}
	}

Полный код примера представлен в нашем топике (поработать с ним можно и на Codepen).

Как обойтись без медиазапросов


Описанный выше лайфхак неплох для работы с Gmail, но остается еще большое количество почто-вых клиентов, которые не поддерживают медиазапросы. Николь Мерлин летом 2015 года опубликовала материал, в котором представила свой способ создания адаптивных писем без использования media queries. Перевод этого материала был опубликован на хабрахабре ранее, поэтому остановимся на основных моментах предложенной техники.

Метод называется «плавающим гибридным» (fluid-hybrid method), который также известен как «эластичный» метод (spongy method). Слово «плавающий» означает, что предлагается использовать большое количество процентных вычислений.

«Гибридный» означает, что для ограничения размеров элементов на больших экранах используется атрибут max-width.

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" />
    <!--[if !mso]><!-->
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <!--<![endif]-->
    <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>
</html>

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

!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" /> – используется для то-го, чтобы смартфоны на базе ОС Windows Phone корректно отображали письмо. Этот тег заключен в условный комментарий, скрывающий его ото всех продуктов mso (Microsoft Outlook), во избежание проблем с отображением изображений в почте Windows Live.

Мы включим сюда тег <title></title>, однако лучше оставить его пустым. Согласно спецификации XHTML, он необходим для корректной работы парсера в предварительном просмотре почтового ящика, однако некоторые из стандартных почтовых приложений Android будут отображать его содержимое прямо перед предзаголовоком письма, что не есть хорошо.

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

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

Первым тегом после «тела» оказывается <center>, центрирующий свое содержи-мое и обладающий несколькими полезными глобальными свойствами (поскольку тэг <body> часто очищается в веб-клиентах). Тег <div class="webkit"> стоит здесь для ранних версий почтовых клиентов на WebKit (это Apple Mail 6 и ниже, а также Outlook 2011). Эти почтовые клиенты поддерживают max-width только для блочных элементов, поэтому проще всего будет «завернуть» все содержимое в этот – теперь нам можно не ограничивать ширину в медиазапросах.

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;
}

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

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

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

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


Мы начнем с одного из самых важных моментов: создания уловной таблицы стилей для Outlook, невидимой для остальных почтовых клиентов. Для Outlook нужна отдельная таблица, потому что мы собираемся использовать свойство max-width, которое он не поддерживает. Только по этой причине нам нужно создать специальные таблицы, в которых задать точные значения ширины в пикселях.



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

В нашем HTML-файле нужно удалить филлер [content goes here] и заменить его нижеследующим кодом. Мерлин говорит, что привыкла выравнивать все условные теги по левому краю с одинаковым отступом, чтобы повысить читаемость, однако по ее мнению, дизайнеры в праве отформатировать все так, как им удобно.

<!--[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]-->

Внутри условной таблицы вы увидите тег <table class="outer"><code>, являющийся нашим ключевым внешним строительным блоком для всех клиентов, кроме Outlook. Мы хотим, чтобы ширина внешней таблицы на маленьких экранах была равна 100%, а на больших не превышала значения в 600 пикселей, поэтому установим значение атрибута <code>width равным 100%, а max-width – 600 пикселей.



Для нашей таблицы установлена ширина в 100%. Максимальная ширина 600 пикселей

Полезный совет: Для простой и быстрой буферизации на мобильных устройствах измените width вашей таблицы с 100% до 95% – это позволит избежать заморочек с padding или медиазапросами.

Давайте вставим эти стили в наш файл styles.css:

.outer {
Margin: 0 auto;
    width: 100%;
    max-width: 600px;
}

Строка Margin: 0 auto; нужна здесь, чтобы отцентрировать нашу таблицу в Yahoo в Chrome. Хотя это свойство здесь только ради Yahoo, Мерлин всегда пишет Margin с большой буквы, чтобы Outlook.com его не игнорировал.

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

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" width="600" alt="" />
        </td>
    </tr>
</table>

Мы определили ширину в пикселях для нашего изображения в HTML, поэтому Outlook отобразит его корректно, но мы перекроем это значение шириной 100% в CSS, чтобы оно свободно масштабировалось в других клиентах.

.full-width-image img {
    width: 100%;
    max-width: 600px;
    height: auto;
}

Мы также установили значение max-width равным 600 пикселей, чтобы оно совпадало с шириной, заданной в HTML, потому что Windows Phone работает некорректно при max-width равном 100%. Мы задали автоматическое определение высоты, чтобы сохранить пропорции изображения.

Теперь вы можете посмотреть превью своего 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 lobor-tis rhoncus ut erat.</p>
                </td>
            </tr>
        </table>
    </td>
</tr>

Добавьте следующие стили в 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>, которые всегда перекрывают ваши.

Таким образом, мы установили значение padding для нашего столбца равным 10 пикселям, сбросили margin для , задали несколько базовых стилей для ссылок и классов h1 и h2 и гарантировали, что содержимое нашего столбца будет выравнено по левой стороне.
Теперь время перейти к самому увлекательному… Нескольким столбцам!

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


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



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

Сначала добавим новую строку в таблицу .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, то эти столбцы помогают задать содержимому ячейки нужный размер.



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

Теперь нужно заменить каждый филлер [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. Все встраиваемые (в том числе inline-block) элементы подчиняются свойству text-align. Поэтому, если мы заключим наши таблицы в <div> со свойством inline-block, то сможем с легкостью управлять их выравниванием, устанавливая атрибут text-align для их контейнера. Вы можете выбрать выравнивание по левому краю, центру или правому краю, а ваши <div> cо свойством inline-block будут «подчиняться». Вы можете задать свойство display: inline-block непосредственно таблице, но только в том случае, если не собираетесь помещать внутрь неё другие таблицы. Вся разметка начинает вести себя странно, если добавить таблицу внутрь таблицы со свойством inline-block, поэтому убедитесь, что inline-block-контейнером является <div>.

Давайте стилизуем нашу ячейку-контейнер .two-column с помощью выбранного выравнивания. Мы также добавим font-size: 0, чтобы избавиться от пробелов между колонками внутри ячейки.

/*Two column layout*/
.two-column {
text-align: center;
    font-size: 0;
}

Теперь мы стилизуем наш inline-block-контейнер <div>, играющий роль нашего столбца:

.two-column .column {
width: 100%;
    max-width: 300px;
    display: inline-block;
    vertical-align: top;
}

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

Вы можете задать атрибут vertical-align равным top, middle или bottom. Значение top<code> для <code>vertical-align задаёт такое поведение, при котором каждый столбец ведёт себя подобно табличной ячейке с HTML-свойством valign="top"; соответственно middle даёт эффект, подобный valign="middle". Обратите внимание, что у вас может быть множество строк, состоящих из <div>, в одной ячейке, а вертикальное выравнивание всегда будет располагать их по принципу строка-за-строкой. Это довольно стильно! Убедись, что выбранное вами значение vertical-align совпадает с valign, установленным для условной таблицы Outlook, потому что Outlook не поддерживает vertical-align. Если выравнивание ведет себя не так, как вы ожидаете, то, вероятно, вы забыли изменить значение valign для условной таблицы.

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

Давайте заменим два филлера [content goes here] следующей разметкой:

<table class="contents">
    <tr>
            <td>
                    <img src="images/two-column-01.jpg" width="280" 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>

Ширина каждого столбца равняется 300 пикселей, padding равняется 10 пикселям с каждой стороны, поэтому для изображения остается 280 пикселей.

Далее мы стилизуем класс .contents, установив его ширину 100%:

.contents {
width: 100%;
}

Теперь давайте стилизуем наш двухстолбцовый макет, чтобы задать размер шрифта и выравнивание текста, установить ширину изображения равной 100% и добавить тексту под изображением padding:

.two-column .contents {
font-size: 14px;
    text-align: left;
}
.two-column img {
    width: 100%;
    max-width: 280px;
    height: auto;
}
.two-column .text {
    padding-top: 10px;
}

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

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


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

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



Пример того, как складываются три столбца при задании атрибута text-align: center



Пример того, как складываются три столбца при задании атрибута 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 этой строке и применить все свойства, установленные для двухстолбцового макета. Этот же CSS задаст стили для наших div-столбцов, которые мы вскоре добавим (их ширина будет составлять 200 пикселей).

/*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%;
    max-width: 180px;
    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" width="180" 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>

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

Принимая во внимание тот факт, что у этого макета нечётное количество столбцов, может получиться так, что два столбца окажутся сверху, а один снизу. Николь Мерлин считает, что такой дизайн все равно выглядит отлично, хотя, иногда, немного странно. Лучшими способами обойти это являются выравнивание по лево-му краю, либо использование множества строк с тремя столбцами (когда их содержимое складывается вертикально на разрешениях среднего размера, то в каждом ряду остается равное количество столбцов).

8. Добавление двухстолбцового макета с боковой панелью


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

Сначала мы добавим строку и ячейку с классом .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, который поддерживает множественные классы.

Добавьте левую таблицу, которая содержит нашу иконку, в первый столбец:

<table class="column left">
<tr>
        <td class="inner">
            <img src="images/sidebar-01.jpg" width="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 .img {
    width: 100%;
    max-width: 80px;
    height: auto;
}

И, наконец, давайте зададим стили текста и цвет ссылки:

.left-sidebar .contents {
font-size: 14px;
    text-align: center;
}
.left-sidebar a {
    color: #85ab70;
}

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

9. Добавление макета с «отраженной» боковой панелью


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

Давайте скопируем всю строку с ячейкой .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" 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»

Сначала вам необходимо добавить атрибут dir="rtl" для контейнера .right-sidebar. Это даст почтовым приложениям понять, что контейнеры нужно выводить справа налево. Открывающий тег должен выглядеть следующим образом:

	<td class="right-sidebar" dir="rtl">

В условном коде для Outlook нам также необходимо добавить атрибут dir=«rtl» для <table>.

Итак, наш открывающий условный комментарий должен выглядеть следующим образом:

<!--[if (gte mso 9)|(IE)]>
<table width="100%" dir="rtl">
<tr>
<td width="100">
<![endif]-->

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

Наша таблица .column-left должна выглядеть следующим образом:

<table class="column left" dir="ltr">
<tr>
        <td class="inner contents">
            <img src="images/sidebar-02.jpg" width="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" 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 .img {
    width: 100%;
    max-width: 80px;
    height: auto;
}
.right-sidebar .contents {
    font-size: 14px;
    text-align: center;
}
.right-sidebar a {
    color: #70bbd9;
}

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

10. Прогрессивное улучшение с медиазапросами


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

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

Итак, добавьте следующее в свой CSS файл:

/*Media Queries*/
@media screen and (max-width: 400px) {
.two-column .column,
    .three-column .column {
        max-width: 100% !important;
    }
    .two-column img {
        max-width: 100% !important;
    }
    .three-column img {
        max-width: 50% !important;
    }
}

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

@media screen and (min-width: 401px) and (max-width: 620px) {
.three-column .column {
        max-width: 33% !important;
    }
    .two-column .column {
        max-width: 50% !important;
    }
}

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

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


Если используемая вами платформа не проводит встраивание кода за вас, то вам нужно сделать это вручную. Сначала удалите тег <link rel="stylesheet" type="text/css" href="styles.css" /> в <head> и замените его на <style type="text/css">. Скопируйте содержимое style.css и вставьте его ниже, а затем поставьте закрывающий тег </style>. Наконец, скопируйте весь файл в бокс на inliner.cm и подождите. После завершения процесса, скопируйте содержимое из бокса, и все готово! Теперь у нас есть полноценное адаптивный HTML-шаблон, содержащий менее 20 строк медиазапросов.

Заключение


Данный метод также не лишен своих минусов. Например, в комментариях к посту на Хабре Артур Кох (@dudeonthehorse) заявил о том, что примеры кода Николь Мерлин являются довольно громоздкими. Кроме того, он указал на то, что представ-ленная техника не будет работать в мобильной почте от «Яндекса», поскольку в ней не поддерживается min и max-width.

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

Комментарии (1)


  1. dudeonthehorse
    09.10.2015 22:08
    +1

    Я пришел к тому, что вовсе не использую медиазапросы при верстке писем кроме пары исключений.
    Например к нас есть трехколоночная выкладка товаров магазина в письме. Без применения медиазапросов получается по одному товару в строке на смартфонах. Каждый из этих товаров занимает примерно 75% от ширины письма. Для нормальных почтовиков, которые понимают медиазапросы я пишу width:50% для элемента товара и таким образом мы получаем по два товара в строке на мобильном почтовом клиенте. Но это частных случай. В основном все же один товар в строке будет лучше, ибо не нужно напрягать зрение, чтобы его рассмотреть.

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

    Также я решил вопрос инлайнинга писем, подключив gulp-inline-css. В процессе работы с ним были выявлены небольшие баги с переносом стилей и Александр, который мне помогает развивать фреймворк отправил разработчику pull-реквест, который был принят. Это приятно.

    К тому же Николь тоже внесла корректировки в свой шаблон письма с момента публикации ее статьи. Возможно кому то это покажется интересным. Вот ее профиль на гитхабе.