При работе с 1С часто возникает задача формирования и отправки электронных писем с табличными данными, например, результатами запросов или отчетов. Однако, столкнувшись с необходимостью автоматического масштабирования этих таблиц при просмотре в различных почтовых клиентах, мы обнаруживаем, что это представляет собой нетривиальную задачу. Давайте вместе разберемся, почему так происходит и какие подходы помогут нам достичь желаемого результата.
Прежде всего, крайне важно осознать, что среда отображения HTML-писем кардинально отличается от обычного веб-браузера. Современные веб-браузеры отлично поддерживают адаптивную вёрстку с использованием CSS, позволяя контенту динамически подстраиваться под размер окна, масштабироваться и перестраиваться на лету.
Однако, почтовые клиенты (такие как Microsoft Outlook, Gmail, Mail.ru, Apple Mail, мобильные почтовые приложения и другие), особенно их более старые версии, имеют очень ограниченную и часто устаревшую поддержку HTML и CSS. Это ключевая причина всех сложностей с версткой писем.
Как мы видим из обсуждения на форуме, многие почтовые клиенты игнорируют до 90% стилей или отрисовывают их по своему усмотрению (Сообщение 2). Это означает, что даже если мы создадим идеально адаптивный HTML-код, который прекрасно выглядит в браузере, он, скорее всего, не будет работать так же или вообще не будет корректно отображаться в большинстве почтовых клиентов. Пользователь на форуме (Сообщение 2) метко подметил, что "Почтовый клиент игнорирует 90% стилей и отрисовывает все по своему усмотрению."
Также важно различать веб-клиенты почты (доступные через браузер, например, Gmail в Chrome) и десктопные почтовые клиенты (устанавливаемые на компьютер, например, Outlook или Thunderbird). Как было замечено в (Сообщение 3), "Почтовый (аутлюк, например) стили вполне себе применяет", что добавляет дополнительный уровень сложности, требуя учитывать специфику каждого клиента.
В связи с этим, главная задача при верстке HTML-писем – обеспечить максимально широкую совместимость и предсказуемое отображение, зачастую жертвуя некоторыми современными дизайнерскими возможностями и сложными интерактивными элементами.
Автор вопроса справедливо интересуется, как HTML-код, который мы создаем, взаимодействует с 1С (Сообщение 14). Важно понимать, что 1С не является HTML-рендерером в контексте отправки письма. 1С просто генерирует HTML-код как обычную текстовую строку. После того, как эта строка с HTML-кодом полностью сформирована в 1С, она передается почтовому серверу для отправки, а затем доставляется почтовому клиенту получателя.
1С и HTML не взаимодействуют друг с другом напрямую в процессе отображения письма. Это было четко отмечено на форуме (Сообщение 15): "html с 1с не взаимодействует вообще. От слова 'никак'." Это означает, что все стили, логика масштабирования и верстка должны быть полностью инкапсулированы в самом HTML-коде, который мы формируем в 1С.
Любые методы или теги HTML, которые мы хотим использовать для масштабирования, должны быть встроены непосредственно в эту генерируемую 1С строку HTML-кода. В конфигураторе 1С мы можем динамически формировать строки с HTML-тегами, стилями и содержанием таблицы. Например, можно использовать методы для работы со строками или же специальные объекты для работы с HTML-документами (хотя для простых писем обычно достаточно прямого формирования строки).
Прежде чем пытаться интегрировать сложный HTML в 1С, мы настоятельно рекомендуем отладить и протестировать HTML-код отдельно от 1С. Создайте простую HTML-страницу с вашей таблицей, примените к ней необходимые стили и протестируйте её в различных почтовых клиентах (Gmail, Outlook Desktop, Outlook Web, Mail.ru, Yandex Mail, Apple Mail и т.д.). Только после того, как вы добьетесь желаемого поведения в большинстве целевых клиентов, переходите к реализации этого HTML в 1С (Сообщение 15).
Учитывая ограничения почтовых клиентов, мы рассмотрим проверенные методы, которые помогут нам добиться наилучшего результата при масштабировании таблиц в письмах и обеспечить максимально предсказуемое отображение.
Исторически сложилось так, что почтовые клиенты гораздо лучше поддерживают верстку на основе HTML-таблиц (теги <table>, <tr>, <td>), чем современную блочную верстку на <div>. Для обеспечения максимальной совместимости и предсказуемого отображения в большинстве клиентов, мы всегда должны использовать табличную верстку для макета всего письма и его содержимого. Это золотое правило верстки HTML-писем.
Представьте, что все ваше письмо — это одна большая таблица, которая служит основным контейнером. Внутри этой главной таблицы могут быть вложены другие таблицы для структурирования различных секций контента, включая вашу основную таблицу с данными из 1С. Такой подход позволяет минимизировать проблемы с отображением и центрированием.
Для создания эффекта адаптивности, мы должны устанавливать ширину родительской таблицы, содержащей все содержимое письма, на 100%. Это позволит ей адаптироваться к размеру экрана почтового клиента. Однако, чтобы избежать слишком широких таблиц на больших мониторах, что может негативно сказаться на читаемости, мы также должны установить максимальную ширину (max-width). Типичные значения для максимальной ширины письма составляют 600-650px.
Для вложенных таблиц, которые непосредственно содержат ваши данные из 1С, также целесообразно устанавливать width: 100%;, чтобы они корректно перестраивались на маленьких экранах внутри своего родительского контейнера. Мы всегда используем атрибуты border="0", cellpadding="0", cellspacing="0" для таблиц, чтобы избежать нежелательных отступов и границ по умолчанию.
Рассмотрим пример структуры:
<table width="100%" border="0" cellpadding="0" cellspacing="0" style="max-width: 600px; margin: 0 auto;">
<!-- Этот контейнер будет центрирован и иметь максимальную ширину 600px -->
<tr>
<td>
<!-- Вложенная таблица для секции контента -->
<table width="100%" border="0" cellpadding="0" cellspacing="0">
<tr>
<td style="padding: 20px; font-family: Arial, sans-serif; font-size: 16px; color: #333333;">
<h3 style="margin: 0 0 15px 0;">Заголовок Вашего Отчета</h3>
<p style="margin: 0 0 10px 0;">Ниже представлена таблица данных из 1С:</p>
<!-- Здесь будет содержимое вашей основной таблицы данных из 1С -->
<table width="100%" border="1" cellpadding="8" cellspacing="0" style="border-collapse: collapse; border-color: #dddddd;">
<tr>
<th style="font-family: Arial, sans-serif; font-size: 14px; color: #ffffff; background-color: #555555; padding: 10px; text-align: left;">Колонка 1</th>
<th style="font-family: Arial, sans-serif; font-size: 14px; color: #ffffff; background-color: #555555; padding: 10px; text-align: left;">Колонка 2</th>
<th style="font-family: Arial, sans-serif; font-size: 14px; color: #ffffff; background-color: #555555; padding: 10px; text-align: left;">Колонка 3</th>
</tr>
<tr>
<td style="font-family: Arial, sans-serif; font-size: 14px; color: #333333; padding: 8px; border: 1px solid #eeeeee;">Данные A1</td>
<td style="font-family: Arial, sans-serif; font-size: 14px; color: #333333; padding: 8px; border: 1px solid #eeeeee;">Данные B1</td>
<td style="font-family: Arial, sans-serif; font-size: 14px; color: #333333; padding: 8px; border: 1px solid #eeeeee;">Данные C1</td>
</tr>
<tr>
<td style="font-family: Arial, sans-serif; font-size: 14px; color: #333333; padding: 8px; border: 1px solid #eeeeee;">Данные A2</td>
<td style="font-family: Arial, sans-serif; font-size: 14px; color: #333333; padding: 8px; border: 1px solid #eeeeee;">Данные B2</td>
<td style="font-family: Arial, sans-serif; font-size: 14px; color: #333333; padding: 8px; border: 1px solid #eeeeee;">Данные C2</td>
</tr>
</table>
</td>
</tr>
</table>
</td>
</tr>
</table>
Поскольку большинство почтовых клиентов игнорируют внешние CSS-файлы и стили, прописанные в тегах <head> и <body>, все стили, которые мы хотим применить, следует добавлять непосредственно в HTML-теги с помощью атрибута style. Этот подход называется "инлайновые стили" и является стандартом де-факто для верстки HTML-писем.
Мы должны использовать только базовые свойства CSS, такие как font-family, font-size, color, background-color, padding, margin, width, height, text-align, vertical-align. Сложные свойства (тени, градиенты, анимации, flexbox, grid) почти наверняка не будут поддерживаться или будут отображаться непредсказуемо.
Пример инлайновых стилей:
<td style="font-family: Arial, sans-serif; font-size: 14px; color: #333333; padding: 10px; background-color: #f9f9f9; text-align: center;">
Ваш текст или ячейка таблицы
</td>
Медиазапросы (@media) – это мощный инструмент для адаптивной верстки в вебе, позволяющий применять разные стили в зависимости от ширины экрана (например, для мобильных устройств). В контексте HTML-писем, их поддержка крайне неоднородна и ограничена.
Как было указано в обсуждении (Сообщение 8, ссылка на Habr), некоторые почтовые клиенты (например, Gmail с 2016 года) стали более толерантны к медиазапросам, но многие другие, особенно десктопные клиенты, продолжают их полностью игнорировать. Поэтому медиазапросы не должны быть нашим основным методом адаптации, а скорее улучшением (прогрессивным улучшением) для тех клиентов, которые их поддерживают. Основная верстка должна быть функциональной и без них. Мы можем размещать медиазапросы в теге <style> внутри <head>, но всегда помним об ограничениях поддержки.
Пример (размещается в теге <head>):
<style type="text/css">
@media only screen and (max-width: 620px) {
/* Эти стили будут применяться только на экранах шириной до 620px */
.full-width-image {
width: 100% !important;
height: auto !important;
}
.hide-on-mobile {
display: none !important;
max-height: 0 !important;
overflow: hidden !important;
mso-hide: all !important; /* Специально для Outlook */
}
.main-table-wrap {
width: 100% !important;
}
.main-table-wrap td {
padding: 10px !important; /* Уменьшаем отступы на мобильных */
}
}
</style>
Чтобы избежать непредвиденных отступов и границ, которые могут быть добавлены некоторыми почтовыми клиентами по умолчанию (что часто ломает макет), мы должны явно сбрасывать их:
border="0", cellpadding="0", cellspacing="0".<body>, <p>, <div>, <td> и т.д.) в письме рекомендуется устанавливать инлайновые стили: style="margin:0; padding:0;". Это поможет предотвратить добавление браузерами и почтовыми клиентами собственных отступов.Пример для тела письма:
<body style="margin: 0; padding: 0; min-width: 100%; background-color: #f0f0f0;">
<center style="width: 100%; background-color: #f0f0f0;">
<!-- Здесь будет находиться основной контейнер письма -->
</center>
</body>
display: block;Если ваше письмо содержит изображения (например, логотип компании, графики из отчета 1С), чтобы избежать лишних отступов вокруг них (часто добавляемых почтовыми клиентами), мы должны применять стиль display: block; к тегу <img>. Также крайне важно всегда указывать атрибуты width и height, и alt для доступности и корректного отображения даже при блокировке изображений.
<img src="ссылка_на_ваше_изображение.jpg" width="600" height="auto" alt="Логотип компании" style="display: block; border: 0; max-width: 100%;">
Microsoft Outlook, особенно старые версии (2007, 2010, 2013, 2016), использует движок рендеринга Microsoft Word, что приводит к специфическим и труднопредсказуемым проблемам отображения. Для корректного отображения в Outlook можно использовать условные комментарии HTML (Conditional Comments).
Эти комментарии позволяют предоставить Outlook специфический макет на основе таблиц, который будет полностью скрыт от других почтовых клиентов. Это часто используется для создания "ghost" таблиц, которые корректируют ширину, центрирование или другие свойства специально для Outlook, не затрагивая при этом отображение в других клиентах.
Пример использования условных комментариев для центрирования основного контейнера письма в Outlook:
<!--[if (gte mso 9)|(IE)]>
<table align="center" border="0" cellspacing="0" cellpadding="0" width="600">
<tr>
<td align="center" valign="top" width="600">
<![endif]-->
<!-- Здесь располагается основной адаптивный контейнер письма, например, ваша <table style="max-width: 600px;"> -->
<div style="max-width: 600px; margin: 0 auto;">
Ваше содержимое письма, например, основная таблица данных.
</div>
<!--[if (gte mso 9)|(IE)]>
</td>
</tr>
</table>
<![endif]-->
Мы должны иметь в виду, что размер HTML-кода письма не должен превышать 100 КБ. Некоторые почтовые клиенты (например, Gmail) могут обрезать длинные письма, если их размер превышает этот лимит, что приведет к неполному отображению контента и, что самое критичное, к потере стилей и нарушению верстки.
Чтобы текст отображался одинаково во всех клиентах и избежать проблем с загрузкой нестандартных шрифтов, мы должны использовать веб-безопасные шрифты. К ним относятся Arial, Helvetica, Georgia, Times New Roman, Verdana, Trebuchet MS. Всегда указывайте запасные шрифты (fallback fonts) на случай, если основной шрифт не будет поддерживаться конкретным почтовым клиентом. Например, font-family: Arial, Helvetica, sans-serif;.
<p style="font-family: Arial, Helvetica, sans-serif; font-size: 16px; color: #333333; line-height: 1.5;">
Пример текста с веб-безопасным шрифтом. Этот текст будет читаемым в большинстве клиентов.
</p>
После того как мы разработали и тщательно протестировали HTML-макет нашей таблицы, используя все вышеперечисленные принципы, мы можем приступить к его формированию непосредственно в 1С. Внешняя обработка, упомянутая автором, — это отличное место для реализации этой логики.
Мы будем использовать возможности 1С для динамического формирования строковой переменной, которая будет содержать весь необходимый HTML-код. В 1С для работы с текстами и строками есть соответствующие методы. Поскольку задача состоит в прямом формировании HTML, мы, скорее всего, будем собирать его по частям путем конкатенации строк.
Разберем по шагам процесс генерации HTML в 1С:
<!DOCTYPE html>, <html>, <head> (с метаданными, такими как кодировка <meta charset="UTF-8"> и заголовком <title>, а также, возможно, медиазапросами в теге <style>), и <body> с инлайновыми стилями для сброса отступов.width="100%" и max-width, а также условные комментарии для Outlook, если это необходимо.ТаблицаЗначений. Мы можем перебирать эти данные в цикле и формировать строки и ячейки таблицы (<tr> и <td>), вставляя в них данные.Представим примерный псевдокод для генерации таблицы данных из 1С:
// Предположим, у нас уже есть ТаблицаЗначений (например, результат запроса)
// с данными для вывода в HTML-таблицу.
// Например, МояТаблицаЗначений с колонками "Наименование", "Количество", "Сумма".
Перем HTML_Код;
HTML_Код = "<!DOCTYPE html>" + Символы.ПС;
HTML_Код = HTML_Код + "<html><head><meta charset="UTF-8"><title>Табличный Документ Из 1С</title>";
HTML_Код = HTML_Код + "<!-- Стили для медиазапросов, если используются. Помним про ограниченную поддержку -->";
HTML_Код = HTML_Код + "<style type="text/css">";
HTML_Код = HTML_Код + " @media only screen and (max-width: 620px) {";
HTML_Код = HTML_Код + " .main-content-table td { padding: 8px !important; font-size: 13px !important; }";
HTML_Код = HTML_Код + " .main-content-table th { padding: 8px !important; font-size: 13px !important; }";
HTML_Код = HTML_Код + " }";
HTML_Код = HTML_Код + "</style>";
HTML_Код = HTML_Код + "</head>";
HTML_Код = HTML_Код + "<body style="margin: 0; padding: 0; min-width: 100%; background-color: #f0f0f0;">";
HTML_Код = HTML_Код + "<center style="width: 100%; background-color: #f0f0f0;">";
// Условные комментарии для Outlook (ghost table)
HTML_Код = HTML_Код + "<!--[if (gte mso 9)|(IE)]>";
HTML_Коod = HTML_Код + "<table align="center" border="0" cellspacing="0" cellpadding="0" width="600"><tr><td align="center" valign="top" width="600">";
HTML_Код = HTML_Код + "<![endif]-->";
// Основной контейнер письма с максимальной шириной и центрированием
HTML_Код = HTML_Код + "<table width="100%" border="0" cellpadding="0" cellspacing="0" style="max-width: 600px; background-color: #ffffff;">";
HTML_Код = HTML_Код + "<tr><td style="padding: 20px;">";
// Заголовок секции письма
HTML_Код = HTML_Код + "<h3 style="font-family: Arial, sans-serif; font-size: 20px; color: #333333; margin: 0 0 15px 0;">Отчет о продажах за период</h3>";
HTML_Код = HTML_Код + "<p style="font-family: Arial, sans-serif; font-size: 14px; color: #555555; margin: 0 0 20px 0;">Уважаемый пользователь, представляем данные по продажам:</p>";
// Начало нашей таблицы данных, которую мы формируем из 1С
HTML_Код = HTML_Код + "<table class="main-content-table" width="100%" border="1" cellpadding="10" cellspacing="0" style="border-collapse: collapse; border-color: #dddddd;">";
// Заголовки таблицы, используя данные из колонок ТаблицыЗначений или фиксированные
HTML_Код = HTML_Код + "<tr>";
HTML_Код = HTML_Код + "<th style="font-family: Arial, sans-serif; font-size: 14px; color: #ffffff; background-color: #555555; padding: 10px; text-align: left; border: 1px solid #444444;">Наименование</th>";
HTML_Код = HTML_Код + "<th style="font-family: Arial, sans-serif; font-size: 14px; color: #ffffff; background-color: #555555; padding: 10px; text-align: right; border: 1px solid #444444;">Количество</th>";
HTML_Код = HTML_Код + "<th style="font-family: Arial, sans-serif; font-size: 14px; color: #ffffff; background-color: #555555; padding: 10px; text-align: right; border: 1px solid #444444;">Сумма</th>";
HTML_Код = HTML_Код + "</tr>";
// Данные таблицы: цикл по ТаблицеЗначений
Для Каждого СтрокаТЗ Из МояТаблицаЗначений Цикл
HTML_Код = HTML_Код + "<tr>";
HTML_Код = HTML_Код + "<td style="font-family: Arial, sans-serif; font-size: 14px; color: #333333; padding: 10px; border: 1px solid #eeeeee; text-align: left;">" + СтрокаТЗ.Наименование + "</td>";
HTML_Код = HTML_Код + "<td style="font-family: Arial, sans-serif; font-size: 14px; color: #333333; padding: 10px; border: 1px solid #eeeeee; text-align: right;">" + Формат(СтрокаТЗ.Количество, "ЧЦ=15; ЧДЦ=0") + "</td>";
HTML_Код = HTML_Код + "<td style="font-family: Arial, sans-serif; font-size: 14px; color: #333333; padding: 10px; border: 1px solid #eeeeee; text-align: right;">" + Формат(СтрокаТЗ.Сумма, "ЧЦ=15; ЧДЦ=2") + "</td>";
HTML_Код = HTML_Код + "</tr>";
КонецЦикла;
HTML_Код = HTML_Код + "</table>"; // Конец таблицы данных из 1С
HTML_Код = HTML_Код + "<p style="font-family: Arial, sans-serif; font-size: 12px; color: #888888; margin-top: 20px;">Это письмо сгенерировано автоматически в 1С. Пожалуйста, не отвечайте на него.</p>";
HTML_Код = HTML_Код + "</td></tr>";
HTML_Код = HTML_Код + "</table>"; // Конец основного контейнера письма
// Закрываем условные комментарии для Outlook
HTML_Код = HTML_Код + "<!--[if (gte mso 9)|(IE)]>";
HTML_Код = HTML_Код + "</td></tr></table>";
HTML_Код = HTML_Код + "<![endif]-->";
HTML_Код = HTML_Код + "</center>";
HTML_Код = HTML_Код + "</body></html>";
// Далее этот HTML_Код передается для отправки по почте, например, через стандартные
// объекты 1С для работы с почтой, такие как ИнтернетПочта или ПочтовыйКлиент.
Мы не можем переоценить важность тщательного тестирования HTML-писем. Поведение HTML-писем сильно различается в зависимости от почтового клиента, операционной системы и устройства. Поэтому, после создания HTML-кода в 1С, мы обязательно должны отправить тестовые письма на различные адреса и проверить их отображение в:
Для этих целей существуют специальные онлайн-сервисы, такие как Litmus или Email on Acid, которые позволяют быстро проверить отображение письма в сотнях различных клиентов и устройств, генерируя скриншоты. Если же доступа к таким сервисам нет, проводите ручное тестирование на максимально возможном количестве реальных устройств и программ, доступных вам.
Как было предложено на форуме (Сообщение 17), если ваш заказчик уверен в возможности реализации желаемого масштабирования, попросите его предоставить образец письма, которое масштабируется так, как ему нужно. Это даст вам конкретный пример для анализа, деконструкции и адаптации, что значительно упростит задачу.
Масштабирование табличного документа в теле письма, формируемого из 1С, — это задача, требующая глубокого понимания ограничений верстки HTML-писем. Отказавшись от современных веб-стандартов в пользу классической табличной верстки с инлайновыми стилями и тщательным тестированием, мы значительно увеличиваем шансы на успешное и предсказуемое отображение в большинстве почтовых клиентов.
Помните, что ключ к успеху лежит в поэтапном подходе: сначала разработка и отладка HTML-верстки отдельно, затем интеграция этого HTML-кода в 1С путем формирования строки, и обязательное, всестороннее тестирование во всех целевых почтовых клиентах. Только так мы сможем добиться наилучшего результата в столь сложной и капризной области, как HTML-письма.