<?xml version="1.0" encoding="utf-8"?> 
<rss version="2.0"
  xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd"
  xmlns:atom="http://www.w3.org/2005/Atom">

<channel>

<title>Блог Михаила Озорнина: заметки с тегом фронтенд</title>
<link>https://mikeozornin.ru/blog/tags/frontend/</link>
<description>Главная · Блог · Работы ·</description>
<author>Михаил Озорнин</author>
<language>ru</language>
<generator>E2 (v3798; Aegea)</generator>

<itunes:owner>
<itunes:name>Михаил Озорнин</itunes:name>
<itunes:email></itunes:email>
</itunes:owner>
<itunes:subtitle>Главная · Блог · Работы ·</itunes:subtitle>
<itunes:image href="" />
<itunes:explicit></itunes:explicit>

<item>
<title>Как выглядит хороший макет</title>
<guid isPermaLink="false">164</guid>
<link>https://mikeozornin.ru/blog/all/what-is-a-good-handoff/</link>
<pubDate>Tue, 11 May 2021 10:19:02 +0300</pubDate>
<author>Михаил Озорнин</author>
<comments>https://mikeozornin.ru/blog/all/what-is-a-good-handoff/</comments>
<description>
&lt;p class="lead"&gt;В продолжении тредов Романа Шамина про дружбу дизайнеров и фронтендеров решил вытащить в блог одну из статей наших гайдов — про то, что такое «хорошо переданный макет». Все вытащенные из гайдов статьи доступны по тегу &lt;a href="http://mikeozornin.ru/blog/tags/guidelines/"&gt;гайдлайны.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Треды Романа Шамина:&lt;br /&gt;
&lt;a href="https://teletype.in/@romanshamin/what-design-want-from-frontend"&gt;teletype.in/@romanshamin/what-design-want-from-frontend&lt;/a&gt;&lt;br /&gt;
&lt;a href="https://teletype.in/@romanshamin/what-frontend-want-from-design"&gt;teletype.in/@romanshamin/what-frontend-want-from-design&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Дальше привожу статью из наших командных договоренностей.&lt;/p&gt;
&lt;h2&gt;О чем эта статья&lt;/h2&gt;
&lt;p&gt;Если макет сделан не очень удобно для разработчиков, это плохо: разработчику будет сложно понять как сделать правильно, он потратит больше времени и где-то ошибется. Дизайнеру придется писать больше замечаний, люди будут менее довольны друг другом.&lt;/p&gt;
&lt;p&gt;Эта статья описывает как хорошо передать макет в разработку.&lt;/p&gt;
&lt;h2&gt;Хранение и состав макетов&lt;/h2&gt;
&lt;h3&gt;Список самих экранов&lt;/h3&gt;
&lt;p&gt;&lt;b&gt;Уровень «Минимально достаточный»&lt;/b&gt;&lt;br /&gt;
Всем членам команды продукта понятно где и как искать макеты:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;где найти макеты по нужной фиче,&lt;/li&gt;
&lt;li&gt;где найти старый макет,&lt;/li&gt;
&lt;li&gt;как понять актуальная версия или нет.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Договоренности команды о процессе выкладывания макетов записаны.&lt;/p&gt;
&lt;p&gt;При обновлении макетов уведомляется проектная команда (аналитик, фронтенд, тех. писатель, QA).&lt;/p&gt;
&lt;h3&gt;Состав экранов&lt;/h3&gt;
&lt;p&gt;&lt;b&gt;Уровень «Минимально достаточный»&lt;/b&gt;&lt;br /&gt;
Для фичи понятен набор экранов, на которые вносятся изменения: какие экраны новые, какие экраны дорабатываются.&lt;/p&gt;
&lt;p&gt;Если экранов несколько, то понятны переходы между экранами.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Уровень «Хорошо»&lt;/b&gt;&lt;br /&gt;
Доступна актуальная схема экранов продукта (карта сайта).&lt;/p&gt;
&lt;p&gt;Если в фиче несколько экранов, то для них сделан кликабельный прототип с переходами между экранами.&lt;/p&gt;
&lt;h2&gt;Экраны&lt;/h2&gt;
&lt;h3&gt;Структура экранов&lt;/h3&gt;
&lt;p&gt;&lt;b&gt;Уровень «Минимально достаточный»&lt;/b&gt;&lt;br /&gt;
Понятна структура экрана: из каких блоков состоит экран, какие между ними соотношения по размерам и отступам.&lt;/p&gt;
&lt;p&gt;Как ведут себя блоки экрана при прокрутке и ресайзе.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Уровень «Хорошо»&lt;/b&gt;&lt;br /&gt;
У продукта есть понятная сетка, описаны типовые лейауты страниц: список, дашборд, форма редактирования, страница просмотра и т. д.&lt;/p&gt;
&lt;h3&gt;Элементы на странице&lt;/h3&gt;
&lt;p&gt;&lt;b&gt;Уровень «Минимально достаточный»&lt;/b&gt;&lt;br /&gt;
По каждому визуальному элементу на макете понятно, что это такое: текст, компонент, иконка, паттерн.&lt;/p&gt;
&lt;p&gt;По каждому компоненту понятно, что это за компонент, какой его режим используется, понятно, если в коде нет этого компонента или функции существующего компонента.&lt;/p&gt;
&lt;p&gt;Понятны размеры элемента, его взаимоотношения с соседними элементами.&lt;/p&gt;
&lt;p&gt;Понятно как элемент тянется, что будет, если в элементе будет меньше или больше контента.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Уровень «Хорошо»&lt;/b&gt;&lt;br /&gt;
Все элементы описаны, разработчик знает где искать документацию на каждый используемый тип элемента: текст, компонент, иконку, паттерн.&lt;/p&gt;
&lt;p&gt;Размеры элементов и отступы между элементами логичны, ожидаемы и понятны.&lt;/p&gt;
&lt;p&gt;Примеры:&lt;/p&gt;
&lt;div class="e2-text-picture"&gt;
&lt;img src="https://mikeozornin.ru/blog/pictures/what-is-a-good-handoff-1@2x.png" width="600" height="88" alt="" /&gt;
&lt;div class="e2-text-caption"&gt;&lt;b&gt;Плохо:&lt;/b&gt; Случайные размеры блоков, фронтендерам сложно понять отступы&lt;/div&gt;
&lt;/div&gt;
&lt;div class="e2-text-picture"&gt;
&lt;img src="https://mikeozornin.ru/blog/pictures/what-is-a-good-handoff-2@2x.png" width="595" height="330" alt="" /&gt;
&lt;div class="e2-text-caption"&gt;&lt;b&gt;Плохо:&lt;/b&gt; Случайные размеры блоков, фронтендерам сложно понять отступ&lt;/div&gt;
&lt;/div&gt;
&lt;div class="e2-text-picture"&gt;
&lt;img src="https://mikeozornin.ru/blog/pictures/what-is-a-good-handoff-3@2x.png" width="600" height="88" alt="" /&gt;
&lt;div class="e2-text-caption"&gt;&lt;b&gt;Хорошо:&lt;/b&gt; Размеры блоков понятны&lt;/div&gt;
&lt;/div&gt;
&lt;div class="e2-text-picture"&gt;
&lt;img src="https://mikeozornin.ru/blog/pictures/what-is-a-good-handoff-4@2x.png" width="600" height="96" alt="" /&gt;
&lt;div class="e2-text-caption"&gt;&lt;b&gt;Хорошо:&lt;/b&gt; Размеры блоков понятны, блоки расположены предсказуемо по сетке&lt;/div&gt;
&lt;/div&gt;
&lt;h3&gt;Кегли&lt;/h3&gt;
&lt;p&gt;&lt;b&gt;Уровень «Минимально достаточный»&lt;/b&gt;&lt;br /&gt;
Для каждого текста на странице понятен стиль или mixin, который нужно взять, эти стили и mixin’ы однозначно определяются из самого макета.&lt;/p&gt;
&lt;p&gt;Эти mixin’ы не противоречат компонентам, паттернам или аналогичным элементам других экранов продуктов.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Уровень «Хорошо»&lt;/b&gt;&lt;br /&gt;
Есть актуальная таблица миксинов, описаны общие принципы их использования.&lt;/p&gt;
&lt;p&gt;Примеры:&lt;/p&gt;
&lt;div class="e2-text-picture"&gt;
&lt;img src="https://mikeozornin.ru/blog/pictures/what-is-a-good-handoff-5@2x.png" width="453" height="168" alt="" /&gt;
&lt;div class="e2-text-caption"&gt;&lt;b&gt;Плохо:&lt;/b&gt; Кегль не замапплен, неясно какой типографический миксин взять&lt;/div&gt;
&lt;/div&gt;
&lt;div class="e2-text-picture"&gt;
&lt;img src="https://mikeozornin.ru/blog/pictures/what-is-a-good-handoff-6@2x.png" width="453" height="206" alt="" /&gt;
&lt;div class="e2-text-caption"&gt;&lt;b&gt;Хорошо:&lt;/b&gt; Кегль и цвет замапплен, понятно что указать&lt;/div&gt;
&lt;/div&gt;
&lt;h3&gt;Цвета&lt;/h3&gt;
&lt;p&gt;Речь идет про цвет любого интерфейсного элемента: текста, иконки, рамки, фона, блока, линии.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Уровень «Минимально достаточный»&lt;/b&gt;&lt;br /&gt;
Не используются цвета не из палитры проекта.&lt;/p&gt;
&lt;p&gt;Переменные цветов подписаны, разработчику легко понять, какую переменную использовать (копировать hex-код не норм).&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Уровень «Хорошо»&lt;/b&gt;&lt;br /&gt;
Составлена таблица цветовых токенов: default text, disabled text, error icon для всех используемых в проекте тем.&lt;/p&gt;
&lt;p&gt;В макетах прилинкованы цвета из этой таблицы (не error-500, а validation-text-color).&lt;/p&gt;
&lt;p&gt;Примеры:&lt;/p&gt;
&lt;div class="e2-text-picture"&gt;
&lt;img src="https://mikeozornin.ru/blog/pictures/what-is-a-good-handoff-7@2x.png" width="453" height="168" alt="" /&gt;
&lt;div class="e2-text-caption"&gt;&lt;b&gt;Плохо:&lt;/b&gt; Цвета не замаплены, неясно какой цвет выбирать&lt;/div&gt;
&lt;/div&gt;
&lt;div class="e2-text-picture"&gt;
&lt;img src="https://mikeozornin.ru/blog/pictures/what-is-a-good-handoff-8@2x.png" width="453" height="206" alt="" /&gt;
&lt;div class="e2-text-caption"&gt;&lt;b&gt;Хорошо:&lt;/b&gt; Цвета замаплены, понятно что указать&lt;/div&gt;
&lt;/div&gt;
&lt;h3&gt;Отступы&lt;/h3&gt;
&lt;p&gt;&lt;b&gt;Уровень «Минимально достаточный»&lt;/b&gt;&lt;br /&gt;
Понятны сами отступы между всеми блоками на странице и их внутренняя логика.&lt;/p&gt;
&lt;p&gt;Отступы на макете не противоречат компонентам (например, в компоненте «кнопка» отступы 6 16, а на макете 6 12).&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Уровень «Хорошо»&lt;/b&gt;&lt;br /&gt;
Описана интерфейсная микросетка и описание модулей.&lt;/p&gt;
&lt;p&gt;Логика отступов описана, есть типовые отступы и их завязка на сетку.&lt;/p&gt;
&lt;h3&gt;Пиктограммы&lt;/h3&gt;
&lt;p&gt;&lt;b&gt;Уровень «Минимально достаточный»&lt;/b&gt;&lt;br /&gt;
Разработчик знает, как вообще подключаются пиктограммы в проект.&lt;/p&gt;
&lt;p&gt;Понятно, что это за конкретная пиктограмма, как ее подключить и вставить.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Уровень «Хорошо»&lt;/b&gt;&lt;br /&gt;
Есть общий список пиктограмм, их коды, параметры вставки в код продукта и документацию.&lt;/p&gt;
&lt;p&gt;&lt;aside class="aside-margin-right"&gt;Чтобы не мучиться со сборкой пакетов иконок, &lt;a href="http://mikeozornin.ru/blog/tags/icon-font/"&gt;почитайте как собирать их автоматически&lt;/a&gt;&lt;/aside&gt;&lt;/p&gt;
&lt;p&gt;Иконки версионируются, к продукту или в документацию можно подключить нужную версию пакета иконок.&lt;/p&gt;
&lt;p&gt;Примеры:&lt;/p&gt;
&lt;div class="e2-text-picture"&gt;
&lt;img src="https://mikeozornin.ru/blog/pictures/what-is-a-good-handoff-9@2x.png" width="453" height="310" alt="" /&gt;
&lt;div class="e2-text-caption"&gt;&lt;b&gt;Плохо:&lt;/b&gt; Иконка не замаплена, нужно искать её в наборе самостоятельно&lt;/div&gt;
&lt;/div&gt;
&lt;div class="e2-text-picture"&gt;
&lt;img src="https://mikeozornin.ru/blog/pictures/what-is-a-good-handoff-10@2x.png" width="453" height="267" alt="" /&gt;
&lt;div class="e2-text-caption"&gt;&lt;b&gt;Хорошо:&lt;/b&gt; Указано какая иконка и из какого набора. Примечание: mc — префикс одного из наших наборов иконок.&lt;/div&gt;
&lt;/div&gt;
&lt;h2&gt;Текст&lt;/h2&gt;
&lt;p&gt;См. также &lt;i&gt;Правильный процесс вычитки&lt;/i&gt; (ссылки нет, статья не вытащена наружу).&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Уровень «Минимально достаточный»&lt;/b&gt;&lt;br /&gt;
Рыба в макете правильная с точки зрения состояний, смысла и точная с точки зрения чисел и значений.&lt;/p&gt;
&lt;p&gt;Нет никаких Значение-1, Значение-2, Значение-3 и Лорем ипсумов.&lt;/p&gt;
&lt;p&gt;Из текста понятно, о чем он: это важно, чтобы техписатели могли его понять и улучшить.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Уровень «Хорошо»&lt;/b&gt;&lt;br /&gt;
Текст в состоянии production-не стыдно, техписатели только полируют его.&lt;/p&gt;
&lt;h2&gt;Состояния&lt;/h2&gt;
&lt;h3&gt;Другие состояния&lt;/h3&gt;
&lt;p&gt;&lt;b&gt;Уровень «Минимально достаточный»&lt;/b&gt;&lt;br /&gt;
Понятно, как сделать все остальные состояния: переключенные вкладки, переключатели, чекбоксы и радиокнопки (если они влияют на компоновку интерфейса).&lt;/p&gt;
&lt;p&gt;Отрисованы или описаны (если этого достаточно) все варианты дропдаунов, селектов и других выпадаек.&lt;/p&gt;
&lt;p&gt;Кроме самих этих состояний описаны переходы между ними.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Уровень «Хорошо»&lt;/b&gt;&lt;br /&gt;
Если блоки меняются значительно, то лучше не пытаться описать отдельные выпадайки, а нарисовать блоки целиком, чтобы было меньше путаницы&lt;/p&gt;
&lt;p&gt;Пример:&lt;/p&gt;
&lt;div class="e2-text-picture"&gt;
&lt;img src="https://mikeozornin.ru/blog/pictures/what-is-a-good-handoff-11@2x.png" width="750" height="1220" alt="" /&gt;
&lt;div class="e2-text-caption"&gt;Хорошо: Нарисованы альтернативные состояний экрана&lt;/div&gt;
&lt;/div&gt;
&lt;h3&gt;Загрузка&lt;/h3&gt;
&lt;p&gt;&lt;b&gt;Уровень «Минимально достаточный»&lt;/b&gt;&lt;br /&gt;
Понятно как загружаются элементы экрана, в какой последовательности, как отображается процесс загрузки.&lt;/p&gt;
&lt;p&gt;Как должен вести себя продукт, если загрузка медленная, элементов много, или загрузка не удалась.&lt;/p&gt;
&lt;h3&gt;Пустое состояние&lt;/h3&gt;
&lt;p&gt;&lt;b&gt;Уровень «Минимально достаточный»&lt;/b&gt;&lt;br /&gt;
Понятно, как выглядит пустое состояние всех блоков и элементов, когда в них нет данных.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Уровень «Хорошо»&lt;/b&gt;&lt;br /&gt;
Пустые состояния систематизированы, используются типовые решения.&lt;/p&gt;
&lt;p&gt;Пример:&lt;/p&gt;
&lt;div class="e2-text-picture"&gt;
&lt;img src="https://mikeozornin.ru/blog/pictures/what-is-a-good-handoff-12@2x.png" width="398.5" height="1000" alt="" /&gt;
&lt;/div&gt;
&lt;h3&gt;Валидация&lt;/h3&gt;
&lt;p&gt;См. &lt;a href="https://mosaic.ptsecurity.com/components/validation/overview"&gt;Валидация данных&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Уровень «Минимально достаточный»&lt;/b&gt;&lt;br /&gt;
Понятно, когда и как срабатывает валидация.&lt;/p&gt;
&lt;p&gt;Как и когда показывается.&lt;/p&gt;
&lt;p&gt;Все сообщения об ошибках проходят через дизайнера, для каждой из возможных ошибок дизайнер придумывает способ предотвращения ошибки или способ отображения, если её нельзя предотвратить&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Уровень «Хорошо»&lt;/b&gt;&lt;br /&gt;
Валидация соответствует общему гайдлайну.&lt;/p&gt;
&lt;p&gt;Валидация способствует не попаданию с ситуацию срабатывания валидации.&lt;/p&gt;
&lt;h3&gt;Много данных&lt;/h3&gt;
&lt;p&gt;&lt;b&gt;Уровень «Минимально достаточный»&lt;/b&gt;&lt;br /&gt;
Понятно как работает экран, когда во всех потенциальных местах (текст, списки, таблицы) будет много данных.&lt;/p&gt;
&lt;p&gt;Все вытащенные из гайдов статьи доступны по тегу &lt;a href="http://mikeozornin.ru/blog/tags/guidelines/"&gt;гайдлайны.&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;См. также&lt;/h2&gt;
&lt;p&gt;Гайд Контура: &lt;a href="https://guides.kontur.ru/principles/layouts/"&gt;guides.kontur.ru/principles/layouts/&lt;/a&gt;&lt;br /&gt;
Чек-лист &lt;a href="https://twitter.com/Prit4er1"&gt;Prit4er1&lt;/a&gt;: &lt;a href="https://www.notion.so/5c03c7554ff542da9c77a6f420935282"&gt;notion.so/5c03c7554ff542da9c77a6f420935282&lt;/a&gt;&lt;/p&gt;
</description>
</item>

<item>
<title>Как включить темную тему на сайте</title>
<guid isPermaLink="false">100</guid>
<link>https://mikeozornin.ru/blog/all/web-dark-mode/</link>
<pubDate>Thu, 13 Dec 2018 10:49:51 +0300</pubDate>
<author>Михаил Озорнин</author>
<comments>https://mikeozornin.ru/blog/all/web-dark-mode/</comments>
<description>
&lt;p class="lead"&gt;Темная тема — модно, все включают её себе в макоси (на следующий день, конечно, выключают обратно). Часто выключают потому, что сама тема темная, а весь контент вокруг (письма, сайты) — светлые. Светлый контент бьет по глазам своей яркостью.&lt;/p&gt;
&lt;p&gt;Некоторые сайты включают темную тему исходя из времени суток. Например, Авиасейлз:&lt;/p&gt;
&lt;div class="e2-text-picture"&gt;
&lt;img src="https://mikeozornin.ru/blog/pictures/dark-mode-aviasales@2x.png" width="846" height="80" alt="" /&gt;
&lt;/div&gt;
&lt;h2&gt;Скоро наступит будущее (UPD. Наступило в macOS 10.14.4)&lt;/h2&gt;
&lt;p&gt;В самой новой версии Сафари (&lt;a href="https://developer.apple.com/safari/technology-preview/"&gt;Safari Technologies Preview&lt;/a&gt;) уже появился детект темной темы внутри браузера. В macOS 10.14.4 эта поддержка появился в обычном сафари.&lt;/p&gt;
&lt;p&gt;Из браузера можно узнать установлена ли темная тема у посетителя и сделать немного магии. Светлая:&lt;/p&gt;
&lt;div class="e2-text-picture"&gt;
&lt;a href="http://mikeozornin.ru" class="e2-text-picture-link"&gt;
&lt;img src="https://mikeozornin.ru/blog/pictures/mikeozornin.ru-light-mode@2x.png" width="1137" height="687" alt="" /&gt;
&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;Темная:&lt;/p&gt;
&lt;div class="e2-text-picture"&gt;
&lt;a href="http://mikeozornin.ru" class="e2-text-picture-link"&gt;
&lt;img src="https://mikeozornin.ru/blog/pictures/mikeozornin.ru-dark-mode@2x.png" width="1137" height="687" alt="" /&gt;
&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;Тем, у кого есть новый Сафари 68+ можно попробовать здесь:&lt;/p&gt;
&lt;p class="loud"&gt;&lt;a href="http://mikeozornin.ru"&gt;mikeozornin.ru&lt;/a&gt; или &lt;a href="http://mikeozornin.ru/blog"&gt;mikeozornin.ru/blog&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Как включить детект&lt;/h2&gt;
&lt;p&gt;Чтобы включить темную тему используется медиа-запрос prefers-color-scheme:&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;@media (prefers-color-scheme: dark) {
    //какие-то отличия темной темы, от светлой
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Чтобы отлаживать, не включая-выключая системную тему, в Сафари (в той самой Technologies Preview) есть кнопка включения темной темы локально в браузере:&lt;/p&gt;
&lt;div class="e2-text-picture"&gt;
&lt;img src="https://mikeozornin.ru/blog/pictures/safari-preview@2x.png" width="1000" height="53" alt="" /&gt;
&lt;/div&gt;
&lt;p&gt;Если кому-то интересно как сделана темная тема, то кроме css-файла на сайте есть &lt;a href="https://github.com/mikeozornin/mikeozornin.ru/blob/master/src/static/css/main-page.less"&gt;less-файл на гитхабе&lt;/a&gt;. Но осторожно, там очень много быдлокода и костылей.&lt;/p&gt;
</description>
</item>

<item>
<title>Как собрать шрифт с иконками — 2</title>
<guid isPermaLink="false">79</guid>
<link>https://mikeozornin.ru/blog/all/how-to-build-icon-font-from-sketch-2/</link>
<pubDate>Tue, 09 Jan 2018 12:12:15 +0300</pubDate>
<author>Михаил Озорнин</author>
<comments>https://mikeozornin.ru/blog/all/how-to-build-icon-font-from-sketch-2/</comments>
<description>
&lt;p class="lead"&gt;С момента &lt;a href="http://mikeozornin.ru/blog/all/how-to-build-icon-font-from-sketch/"&gt;первого поста&lt;/a&gt; я доработал схему сборки, расскажу что и зачем там сделано. Сначала будет вступление-рассказ о чем все это, если вы хотите нового, прокрутите до заголовка &lt;a href="http://mikeozornin.ru/blog/all/how-to-build-icon-font-from-sketch-2#new" class="nu"&gt;«&lt;u&gt;Новое в этой версии&lt;/u&gt;»&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Что вообще происходит&lt;/h2&gt;
&lt;p&gt;У дизайнера есть несколько разных способов передать иконки разработчику:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;отдельными файлами или спрайтом в ПНГ,&lt;/li&gt;
&lt;li&gt;отдельными файлами или спрайтом в СВГ,&lt;/li&gt;
&lt;li&gt;иконочным шрифтом.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Разработчики фронтенда все чаще привыкли использовать иконки в виде шрифта. Этим же способом распространяются популярные иконочные наборы (например, Font Awesome). У нас в компании разработчики тоже просят «дай шрифт». Мы некоторое время отлаживали схему сборки шрифта: как из файла Скетча автоматически получить файл, пригодный для фронтенда, не замучив дизайнера.&lt;/p&gt;
&lt;p&gt;Рассказ может быть полезен разработчикам фронтенда и дизайнерам интерфейсов. В меньшей степени он будет полезен бекендным разработчикам интерфейсов (классический ASP.NET MVC или что-то подобное): схема будет та же, но не будет готовых файлов конфигураций и скриптов. Если кто-то расскажет как прикрутить к этому NuGet, напишите, я добавлю.&lt;/p&gt;
&lt;h2&gt;Зачем это делать, есть же фонтелло&lt;/h2&gt;
&lt;p&gt;Есть много готовых сервисов, которые собирают шрифт по загруженным СВГ-файлам, например fontello. Мы не стали использовать ни один из них, потому что с ними могут быть сложности:&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Дизайнер может случайно сломать шрифт&lt;/b&gt;. Если забыть и не экспортировать иконку, которую уже давал, то следующая версия шрифта будет без него и в неизвестном месте сломается интерфейс. Ситуацию усугубляет факт, что дизайнеров у каждого продукта несколько, а общий набор иконок пополняют 5-6 человек.&lt;/p&gt;
&lt;p&gt;Хорошее решение — простое, в нем минимум ручных действий.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Нескольким дизайнерам работать непросто&lt;/b&gt;. Если несколько дизайнеров поддерживают один шрифт, то возникает много вопросов синхронизации: где хранить исходники, файлы СВГ и файлы шрифта, кто собирает и кому передает, как не забыть иконку.&lt;/p&gt;
&lt;p&gt;Хорошее решение позволяет добавлять иконки скольким угодно дизайнерам так, что они не испортят чужую работу.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Cложно интегрировать в общий процесс сборки продукта&lt;/b&gt;. Отдельно стоящий сервис тяжело встроить в общий процесс разработки и сборки, а у кого-то есть еще и процесс CI. Придется вручную собирать сервисом файл, куда-то его загружать и как-то версионировать.&lt;/p&gt;
&lt;p&gt;Хорошее решение встраивается в процесс разработки.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Не всех устраивает внешний сервис&lt;/b&gt;. Многие компании не верят во внешние сервисы: они могут изменить набор функций, упасть во время подготовки релиза, стать платными или закрыться. В конце концов, их могут хакнуть. Мы — ИБ-компания, и каждый раз раздражать профессионально деформированных безопасников и разработчиков наличием внешнего сервиса не хочется.&lt;/p&gt;
&lt;p&gt;Хорошее решение работает внутри компании.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Формируется не всё, что надо&lt;/b&gt;. Некоторые сервисы выдают шрифт, а иконки кодируют номерами символов. К сожалению, на эти номера полагаться нельзя. Если убрать иконку или поменять порядок, то в следующий раз сервис может выдать совсем другие коды и все иконки непредсказуемо поменяются.&lt;/p&gt;
&lt;p&gt;Если не формировать вместе со шрифтом ЛЕСС-файл, то разработчикам придется в каждом использовании иконки указывать размер кегля, они могут забыть или ошибиться.&lt;/p&gt;
&lt;p&gt;Хорошее решение дает разработчикам все что нужно. Иконка кодируется понятным названием, коды символов и размер подставляются автоматически.&lt;/p&gt;
&lt;h2&gt;Новое в этой версии &lt;span id="new"&gt;&amp;nbsp&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;Раньше я описывал схему сборки шрифта, которая позволяет автоматически собрать шрифтовой файл с иконками из исходника Скетча, сгенерировать для него демо-страницу и ЛЕСС-файл, а также опубликовать пакет в НПМ-репозиторий.&lt;/p&gt;
&lt;p&gt;В новой версии мы научились ещё два важных пункта: поставлять иконки в виде скетч-библиотеки и ТТФ-файла. Я пройдусь по каждому изменению, а в конце приложу итоговое решение.&lt;/p&gt;
&lt;h3&gt;Поставка иконок в виде библиотеки Скетча&lt;/h3&gt;
&lt;p&gt;&lt;aside class="aside-margin-right"&gt;&lt;span class="related-title"&gt;&lt;a href="https://medium.com/ux-power-tools/sketch-libraries-how-they-work-and-the-crazy-stuff-you-can-do-with-them-fc10f142ac80"&gt;Описание работы библиотек&lt;/a&gt;&lt;/span&gt;&lt;/aside&gt;&lt;/p&gt;
&lt;p&gt;С момента написания того поста вышла новая версия Скетча — 47, в ней появились библиотеки символов. Иконки стало удобно вставлять в макеты именно с помощью библиотеки.&lt;/p&gt;
&lt;p&gt;Чтобы сделать один символ на одну иконку и не плодить их для каждого цвета, нужно сделать так:&lt;/p&gt;
&lt;ol start="1"&gt;
&lt;li&gt;Сделайте по символу для каждого цвета, в которые у вас можно красить иконки.&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="e2-text-picture"&gt;
&lt;img src="https://mikeozornin.ru/blog/pictures/icons-BG@2x.png" width="557" height="183" alt="" /&gt;
&lt;/div&gt;
&lt;ol start="2"&gt;
&lt;li&gt;Нарисуйте иконку и наложите её маской на символ цвета:&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="e2-text-picture"&gt;
&lt;img src="https://mikeozornin.ru/blog/pictures/icon-in-library@2x.png" width="368" height="158" alt="" /&gt;
&lt;/div&gt;
&lt;p&gt;После этого вы сможете менять цвет иконок через оверрайды:&lt;/p&gt;
&lt;div class="e2-text-picture"&gt;
&lt;img src="https://mikeozornin.ru/blog/pictures/icon-in-library-2@2x.png" width="376" height="229" alt="" /&gt;
&lt;/div&gt;
&lt;p&gt;Образец файла: &lt;a href="https://github.com/mikeozornin/icon-font-public/raw/master/iconset.sketch"&gt;iconset.sketch&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;К сожалению такой скетч-файл плохо собирался в шрифт. Это происходит из-за маски.&lt;/p&gt;
&lt;p&gt;Маска правильно экспортируется в СВГ-файл, но в шрифте нет понятия маски, в итоге иконки ломались. Долгое время я вел скетч-файл в двух вариантах: простые артборды для шрифта и такие же с маской для библиотеки. Но это плохой способ: нужно добавлять и изменять пары одинаковых иконкок. Из-за этого иногда были ошибки — я что-то где-то забывал.&lt;/p&gt;
&lt;p&gt;Неожиданно Акронис &lt;a href="https://habrahabr.ru/company/acronis/blog/344454/"&gt;написал пост на Хабре&lt;/a&gt; про свою дизайн-систему. С помощью их поста удалось сделать правильно. Сейчас наш сборщик регулярными выражениями вырезает лишнее из СВГ-файла и превращает файл с маской в обычный файл.&lt;/p&gt;
&lt;p&gt;Для вырезания лишнего я подключил grunt-text-replace, вот его конфиг:&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;replace: {
  remove_mask: {
    src: [PATH_BUILD_ICONS + '/*.svg'],
     overwrite: true,  // overwrite matched source files
     replacements: [
      {from : / fill=&amp;quot;(.*?)&amp;quot;/m,             to : ''},
      {from : /(\s*)&amp;lt;\/defs[\s\S]*&amp;lt;\/g&amp;gt;/m,  to : ''},
      {from : /(\s*)&amp;lt;defs&amp;gt;/m,               to : ''},
      {from : / id=&amp;quot;(.*?)&amp;quot;/m,               to : ''},
      {from : /xmlns:xlink=&amp;quot;(.*?)&amp;quot;/m,       to : ''},
      {from : /(\s*)&amp;lt;g[\s\S]*?&amp;gt;/m,          to : ''},
      {from : /(\s*)&amp;lt;\/g&amp;gt;/m,                to : ''},
      {from : /&amp;lt;svg/m,                      to : '&amp;lt;svg fill=&amp;quot;#000&amp;quot;'},
      {from : / transform=&amp;quot;(.*?)&amp;quot;/m,        to : ''},
      {from : / fill-rule=&amp;quot;(.*?)&amp;quot;/m,        to : ''},]            
    }
  }&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;Поставка иконок в виде ТТФ-файла&lt;/h3&gt;
&lt;p&gt;У нас в компании есть команда технических писателей, которые пишут руководства по продуктам. В руководствах техписатели вставляют иконки, чтобы проиллюстрировать на что нужно нажать в интерфейсе.&lt;/p&gt;
&lt;p&gt;Раньше для вставки иконки они делали скриншот экрана, вырезали из него иконку и вставляли в руководство. Сказать, что это неудобный способ — ничего не сказать: растровые скриншоты плохо выглядят при печати; при изменении иконки нужно внимательно заменить все скриншоты с ней; сложно менять цвет иконок в растре, их приходится снимать в каждом цвете — это все увеличивает и без того большую работу.&lt;/p&gt;
&lt;p&gt;Редактор документации поддерживает вставку через СВГ, она решила бы почти часть этих проблем, но СВГ легко не перекрасить, и СВГ-картинки плохо выглядит при редактировании.&lt;/p&gt;
&lt;p&gt;Идеальным вариантом для них было бы использовать ТТФ-шрифт: он отлично рендерится на экране и при печати, хорошо автоматизируется и удобно перекрашивается.&lt;/p&gt;
&lt;p&gt;Однако недостаточно просто включить генерирование ТТФ-файла: по умолчанию коды символов формируются сборщиком автоматически. При следующем формировании шрифта код иконки мог замениться на произвольный. Если технический писатель вставлял иконку в документ, и обновлял шрифт, часть иконок могла непредсказуемо поменяться на другие. Так, конечно, никуда не годилось.&lt;/p&gt;
&lt;p&gt;В новой версии вместо автоматического выбора кодов символов я задаю их руками. Меинтейнер шрифтового репозитория (это я) выдает каждой новой иконке новый код и следит за тем, чтобы коды не менялись. Для этого используется секция codepoints в grunt-webfont. Каждой иконке нужно задать номер символа. У нас используется последовательная нумерация начиная с 0xF501.&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;codepoints : {
   'upload-to-cloud_24' : 0xF501,
   'upload-to-cloud_64' : 0xF502,
},
startCodepoint: 0xF701,&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Иконкам, которым номер не выставлен вручную, код выберется автоматически. Вообще это неправильно и лучше следить, чтобы таких иконок не было. Чтобы найти такие иконки их пространство имен отличается, им выдается номер из пространства 0xF701+, поэтому они всегда будут в конце шрифта и их легко найти.&lt;/p&gt;
&lt;p&gt;Посмотреть коды символов можно с помощью &lt;a href="http://opentype.js.org."&gt;http://opentype.js.org.&lt;/a&gt; Выбираете Glyph Inspector, загружаете шрифт и смотрите:&lt;/p&gt;
&lt;div class="e2-text-picture"&gt;
&lt;img src="https://mikeozornin.ru/blog/pictures/opentype.js@2x_1.png" width="1886" height="1398" alt="" /&gt;
&lt;/div&gt;
&lt;p&gt;Наши писатели перешли на ТТФ-файл и довольны.&lt;/p&gt;
&lt;div class="post-summary"&gt;&lt;div class="post-summary__header"&gt;&lt;p&gt;Скачать и посмотреть&lt;/p&gt;
&lt;/div&gt;&lt;div class="post-summary__text"&gt;&lt;p&gt;Я обновил репозиторий решения, там есть пример файла и сборщик. Чтобы понять как и что — прочитайте README.md. Скачивайте и смотрите:&lt;br /&gt;
&lt;a href="https://github.com/mikeozornin/icon-font-public"&gt;https://github.com/mikeozornin/icon-font-public&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;&lt;/div&gt;&lt;h2&gt;Что дальше&lt;/h2&gt;
&lt;p&gt;Наша схема сейчас покрывает нужны дизайнеров, фронтендеров и технических писателей. Немного не хватает нормального предпросмотра шрифта (пока не хватает времени доделать). Напишу, если будет что показать.&lt;/p&gt;
&lt;p&gt;С вопросами, багрепортами или советами — в телеграм &lt;a href="http://t.me/mikeozornin"&gt;@mikeozornin&lt;/a&gt; или на почту &lt;a href="mailto:mike.ozornin@gmail.com"&gt;mike.ozornin@gmail.com&lt;/a&gt;.&lt;/p&gt;
</description>
</item>

<item>
<title>Как собрать шрифт с иконками</title>
<guid isPermaLink="false">54</guid>
<link>https://mikeozornin.ru/blog/all/how-to-build-icon-font-from-sketch/</link>
<pubDate>Thu, 26 Jan 2017 12:21:17 +0300</pubDate>
<author>Михаил Озорнин</author>
<comments>https://mikeozornin.ru/blog/all/how-to-build-icon-font-from-sketch/</comments>
<description>
&lt;p class="lead"&gt;Разработчики иногда просят иконки не в пнг или свг, не пнг-спрайтом, а в шрифте. Им проще его так использовать. В посте я расскажу как из скетч-файла собрать шрифт, чтобы всем было удобно в будущем.&lt;/p&gt;
&lt;p class="lead"&gt;UPD. Появилась &lt;a href="http://mikeozornin.ru/blog/all/how-to-build-icon-font-from-sketch-2/"&gt;более новая версия сборки&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Зачем это делать, есть же фонтелло&lt;/h2&gt;
&lt;p&gt;Есть много сервисов, которые собирают шрифт из загруженных свг-файлов. Зачем придумывать что-то своё?&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Чтобы случайно не сломать шрифт&lt;/b&gt;. Если забыть иконку, которую уже выдавал и не загрузить в фонтеллу, то она не попадет в новый шрифт и где-то в интерфейсе пропадет иконка.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Подойдет, если дизайнеров несколько&lt;/b&gt;. Если дизайнеров в команде несколько, то нужна синхронизация между ними. Было бы круто, если бы каждый мог добавлять в шрифт иконки и не сломать чужой результат.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Легко встраивается в ваш CI-процесс&lt;/b&gt;.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Не всех устраивает внешний сервис&lt;/b&gt;. Внешний сервис может быть недоступен, он может внезапно обновиться, стать платным, и вообще не все готовы отдавать наружу свои иконки.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Разработчику сразу формируется и less-файл&lt;/b&gt;. Обмениваться кодами символов неудобно, они генерируются автоматически и могут измениться, использовать css-класс надежно, он не поменяется.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Вариант 1. Собираем и отдаём шрифт&lt;/h2&gt;
&lt;p&gt;Я выложил все необходимые файлы в репозиторий &lt;a href="https://github.com/mikeozornin/icon-font-public"&gt;icon-font-public&lt;/a&gt;, скачайте его и распакуйте куда-нибудь.&lt;br /&gt;
Скачать: &lt;a href="https://github.com/mikeozornin/icon-font-public/archive/master.zip"&gt;https://github.com/mikeozornin/icon-font-public/archive/master.zip&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Шаг 1. Настраиваем среду&lt;/h3&gt;
&lt;p&gt;Все эти заклинания надо произнести один раз, дальше не понадобятся&lt;/p&gt;
&lt;p&gt;1) Установить &lt;a href="http://brew.sh/index_ru.html"&gt;brew&lt;/a&gt;. Brew — это такой менеджер пакетов, который легко позволяет ставить программы и библиотеки. Выполнить в терминале команду:&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;/usr/bin/ruby -e &amp;quot;$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)&amp;quot;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;2) С помощью brew установить шрифтообработчики:&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;brew install ttfautohint fontforge --with-python&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;3) Установить node.js, скачать тут &lt;a href="https://nodejs.org/en/"&gt;https://nodejs.org/en/&lt;/a&gt; current-версию.&lt;/p&gt;
&lt;p&gt;4) Установить SketchTool&lt;br /&gt;
При установленном Sketch выполнить в терминале команду:&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;/Applications/Sketch.app/Contents/Resources/sketchtool/install.sh&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;5) Установить grunt&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;npm install -g grunt-cli&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;Шаг 2. Сборка файла шрифта&lt;/h3&gt;
&lt;p&gt;Для сборки шрифт нужно произнести в терминале заклинание:&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;./build.sh&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Если в первый раз не сработает, сделайте скрипт выполняемым:&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;chmod +x build.sh&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;В итоге при добавлении иконки нужно будет сделать:&lt;/p&gt;
&lt;ol start="1"&gt;
&lt;li&gt;Нарисовать иконку.&lt;/li&gt;
&lt;li&gt;Собрать шрифт: ./build.sh&lt;/li&gt;
&lt;li&gt;Отдать файл шрифта и less-файл разработчику&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;Что все это было?&lt;/h3&gt;
&lt;p&gt;Всё, что описано выше работает так:&lt;/p&gt;
&lt;ol start="1"&gt;
&lt;li&gt;С помощью SketchTool всё, что может быть экспортировано, экспортируется из скетча в СВГ-файлы.&lt;/li&gt;
&lt;li&gt;СВГ-файлы, полученные на шаге выше собираются в шрифт. Для этого запускается сборщик шрифта, который все СВГ-файлы собирает в шрифт, конвертирует его в нужный формат и формирует хтмл-страницу с превью.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;Вариант 2. Собираем и отдаём шрифт npm-пакетом&lt;/h2&gt;
&lt;h3&gt;Это ещё что такое?&lt;/h3&gt;
&lt;p&gt;Фронтенд-разработчики подключают библиотеки через npm-пакеты. Это привычная и удобная для них среда, кроме этого, npm-пакет сделает передачу шрифта удобней.&lt;/p&gt;
&lt;h3&gt;Шаг 1. Настраиваем среду&lt;/h3&gt;
&lt;p&gt;Нужно настроить среду как в первом варианте, и дополнительно настроить локальный npm-репозиторий. Спросите вашего фронтендера как это сделать у вас в команде. Попросите его исправить файл package.json.&lt;/p&gt;
&lt;h3&gt;Шаг 2. Сборка файла шрифта&lt;/h3&gt;
&lt;ol start="1"&gt;
&lt;li&gt;Нарисовать иконку.&lt;/li&gt;
&lt;li&gt;Собрать шрифт: ./build.sh&lt;/li&gt;
&lt;li&gt;Изменить версию пакета в файле package.json&lt;/li&gt;
&lt;li&gt;Выполнить команду grunt publish&lt;/li&gt;
&lt;li&gt;Передать разработчику шифровку «Выпустил пакет версии xxx».&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;Вариант 3. Собираем и отдаём шрифт нугет-пакетом&lt;/h2&gt;
&lt;p&gt;К сожалению про нугет ничего не знаю, но если кто-то соберет рабочий вариант, добавлю.&lt;/p&gt;
&lt;h2&gt;На что обратить внимание при рисовании иконок&lt;/h2&gt;
&lt;p&gt;При экспорте иконок надо не забыть перевести все в кривые. Чего не должно быть:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Радиусов скруглений&lt;/li&gt;
&lt;li&gt;Покрашенным рамок&lt;/li&gt;
&lt;li&gt;Текстовых надписей&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Если это будет, то иконка может выглядеть в шрифте плохо, даже если в СВГ-файле было всё ок.&lt;/p&gt;
&lt;h2&gt;Если что-то не работает&lt;/h2&gt;
&lt;p&gt;Я обкусывал наше решение, возможно что-то переобкусал. Пишите если что-то не работает, или попросите помочь вашего фронтендера, он разберется.&lt;/p&gt;
</description>
</item>


</channel>
</rss>