Мы почти полностью перевели проекты на векторную графику, хотя еще полгода назад были адептами символьных шрифтов (шучу, не такими уж и адептами). В статье я расскажу с какими сложностями мы столкнулись в процессе, что из этого получилось, и почему вам стоит переходить на SVG уже в следующем проекте.
Как я уже сказал, нам нравились иконочные шрифты. Наверное, нравились бы и дальше, если бы не десяток проблем. Зато шрифт легко подключить и использовать: кладем его и стили в папку, пишем в верстке <span class="icon-search"></span> — и в нужном месте появляется пиктограмма. Удобно!
Идея и задача
Удобно, только будущее за вектором. Когда мы задумались о переходе на SVG, решили начать не с технологий, как мы, программисты, любим, а с интерфейса. Чего мы хотим от графики для веб-проектов? Как нам было бы удобно работать с ней? Отличается ли это удобство для разработчика и дизайнера? Если делать набор SVG-иконок как самостоятельный продукт, какие преимущества у него должны быть?
Вопросы помогли понять задачу. Мы хотим:
- Легко подключать иконки к любому проекту — от блога на WP до веб-приложения на Rails.
- Использовать декларативный стиль: «Вот здесь должна быть иконка шестеренки».
- Менять цвет и трансформировать иконки с помощью CSS.
- Поменьше работать руками, побольше перекладывать на машину.
Начало работы
Из всех возможных способов подключения я выбрал спрайт как самый надежный. Выглядит он примерно так:
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="display:none">
<symbol id="foo-icon" viewBox="0 0 50 50">...</symbol>
<symbol id="bar-icon" viewBox="0 0 50 50">...</symbol>
...
</svg>
А иконка foo показывается вот так:
<svg><use xlink:href="#foo-icon"></use></svg>
Спрайт строится с использованием symbol, а не defs, для того, чтобы вьюбокс иконки был определен только в одном месте — в самом спрайте, и нам не пришлось указывать его при показе иконок. К тому же, это дает больший контроль над внешним видом дизайнеру, потому что пропорции вьюбокса всегда одинаковы.
Мы разрабатываем на Ruby on Rails, поэтому автоматизировали процесс средствами этого фреймворка. Я написал rake-задачу для генерации спрайта из набора SVG-файлов (после их предварительной очистки с помощью svgo) и пару хелперов для подключения скомпилированного спрайта и рендеринга иконок.
В самом начале сборщик иконок был просто частью одного из разрабатываемых нами проектов. Через некоторое время похожая задача возникла еще на одном проекте, а потом еще на одном. Так мы решили нарисовать набор часто используемых иконок, выделить его в отдельную библиотеку и сделать использование простым не только в наших проектах, но и в чужих.
Дизайн
Передаю клавиатуру romanshamin — дизайнеру проекта.
Привет!
Я сформулировал задачу так: сделать практичный набор пиктограмм. Только базовые иконки, нужные в обиходе большинства сайтов. Лупа — поиск, крестик — закрыть, вот это все. Второе ограничение: не выпендриваться с авторским стилем. Наоборот, пусть стиль иконок растворится в мейнстриме и так подойдет большинству.
Важный сосед — текст
В композиционной вселенной интерфейса текст — самый близкий к пиктограммам объект. Это прочная связь, и было бы ошибкой игнорировать ее при разработке. Нужен подопытный образец, как ориентир для графики. Посмотрим, чем отличается текст среднего современного сайта от собрата пятилетней давности.
- Набор стал крупнее. 16—24 пикселей сейчас, против 12—14 в прошлом.
- Шрифты стали разнообразнее. Прощай, Ариал.
- Благодаря экранам с высокой плотностью пикселей для основного текста стали чаще выбирать светлые начертания. Light и extra light соперничают с regular.
Источник: Smashing Magazine. Раздел Average Font Size For Body Copy за 2009 и 2013.
Для сайтов и приложений привычнее шрифты без засечек, поэтому исключаю антиквы. Итак, портрет: светлый гротеск большого размера. Выбираю Helvetica Neue Light — пусть на первых порах отдувается за все шрифты интернета.
А как же нормальные и полужирные начертания?
Нужно больше ограничений
Мы решили делать два стилистических набора: контурный и со сплошной заливкой. Первый годится для светлых шрифтов. Второй закроет насыщенности от нормальной до сверхжирной. Первый менее практичен, зато накладывает больше ограничений. Значит, с ним мы встретим и решим больше потенциальных проблем. С него и начнем.
Решение про два набора основано на давней идее про умные SVG-иконки, которые с помощью CSS можно подстроить под насыщенность и стиль шрифта. Здравым смыслом и экспериментами мы согнали с идеи лишний жир, который мог бы поглотить непредсказуемое количество времени, и сосредоточились на том, что способны сделать быстро.
Размер, оптика и четкость
Теперь нужно выбрать размер базовых квадрата и круга. Эти фигуры определят оптический вес каждой пиктограммы. Оптический вес — интересная штука. Если поставить рядом квадрат высотой 15 пикселей и круг такого же диаметра, то круг будет казаться меньше. Чтобы компенсировать эффект, круг нужно увеличить. Для нашего квадрата близким по оптическому весу будет круг диаметром 17 пикселей.
Вообще, в идеальных условиях иконкам не нужен никакой размер. Идеальные фигуры увеличиваются и уменьшаются без побочных эффектов. Идеальная среда отображения имеет бесконечную разрешающую способность. Идеальные иконки в идеальной среде выглядят четко при любом размере.
Мы же имеем дело с экраном — средой низкого разрешения. Даже на ретине опытный глаз различает пиксели. В графическом мире пиксели как гравитация — влияют на все видимое глазом. Фигура на экране выглядит четко, если границы ее контуров совпадают с границами пиксельной сетки экрана. Если пиксели не учитывать, получится размазня (на рисунке слева). Поэтому нужно выбрать базовый размер — чтобы знать достаточно ли пикселей для создания четких форм.
Стоит упомянуть, что можно хранить разные SVG-изображения для одной пиктограммы и показывать каждое в нужный момент. Сейчас эту технологию применяют, чтобы в крупном размере получать детальное изображение, а в мелком — попроще. Мы планируем сделать несколько оптимизированных под пиксельную сетку размеров одной иконки и переключать их в зависимости от размера текста рядом. Теоретически, может получиться что-то похожее на шрифтовой хинтинг.
Возвращаюсь к исходной задаче: нужно найти такой размер базового круга, чтобы он сносно подходил к большинству популярных размеров основного текста. У меня три переменных: размер текста, диаметр круга и толщина штриха буквы. Перебирать их отношения вручную было лень и я запилил инструмент — лучше день потерять, потом за пять минут долететь. Разместил на странице надписи от 13 до 24 пикселей, рядом — базовый круг, прикрутил слайдер и принялся сравнивать.
Теперь можно открывать Иллюстратор, продумывать организацию рабочего файла, придумывать вспомогательную сетку, рисовать пиктограммы, сомневаться и перерисовывать заново, выбирать понятные образы, чистить вектор, следить за оптическим весом, постоянно проверяя, как свежая иконка смотрится рядом с текстовой строкой. Боюсь, эта узкая тема будет интересна не всем, поэтому закончу здесь.
Спасибо за внимание!
Проблемы, с которыми мы столкнулись
В момент написания гема я избавился от svgo в пользу малоизвестного svg_optimizer, написанного на Ruby. Впоследствии эта замена стала причиной появления зубцов при рендеринге иконок — оптимизатор чересчур старательно оптимизировал структуру SVG и дублировал код иконки. В результате вместо одной получались две, наложенные друг на друга.
После этого прокола svg_optimizer заменили на svgo, а у svgo отключили плагин mergePaths, портящий форму иконок.
Еще мы обернули иконку в дополнительный элемент, на это есть две причины. Первой проблемой стало нежелание jQuery менять классы SVG-элемента (с ванильным JS все работает отлично). А вторая проблема заключается в том, что события непосредственно на SVG-элементе не ловятся — нужно слушать их на обертке.
Из нерешаемого в данный момент: в Сафари контуры слегка «пожеваные».
Evil Icons
Мы сразу делали иконки по принципам разработки больших продуктов. Определяли целевую аудиторию и конкурентные преимущества. Проект изначально предполагался как свободный и бесплатный. Несмотря на это, мы спрашивали себя: если бы мы брали за иконки деньги, то что в них должно быть хорошего, чтобы человек согласился заплатить? Это помогало держать ум в тонусе и не отвлекаться на «просто прикольные фичи».
Мы сделали предварительный анонс и получили первую обратную связь. Благодаря ей буквально за пару дней иконки стали заметно лучше. Пользуясь случаем, благодарим всех, кто указывал на косяки и помогал их исправлять. Из-за вас, ребята, мы любим опенсорс, спасибо! :-)
Теперь настало время поделиться с хабражителями.
Представляем Evil Icons — набор бесплатных SVG-иконок для сайтов и веб-приложений. В комплекте: Node.js пакет и Ruby гем для разработчиков, файлы .ai и .sketch для дизайнеров.
Скоро выпустим дополнительные стили, дадим возможность добавлять в набор собственные иконки. Подумываем сделать плагины для Grunt и Gulp, а также подключение через CDN.
* * *
Иконки развиваются по пути, схожему с шрифтами. Раньше рисованный шрифт был обычным делом, а сегодня все используют чужие разработки. Теперь и веб-дизайнеры все реже делают иконки самостоятельно и все чаще используют готовые наборы.
Бесспорно, у SVG свои проблемы. Однако, очень похоже, что ситуация будет выправляться. Браузеры будут все лучше поддерживать SVG, что видно уже сейчас. Экранов с высокой плотностью пикселей станет больше. Через пару лет, может быть, появятся мониторы с еще более высокой плотностью пикселей. Тем, кто работает с растром, придется готовить ассеты в @2x—@Nx и кто знает, насколько большим будет N.
Evil Icons — это самая доступная на текущий момент возможность перейти на SVG уже в вашем следующем проекте.
Автор: OutPunk