Pull to refresh

Evil Icons: как мы изобретали SVG-иконки

Reading time8 min
Views48K


Мы почти полностью перевели проекты на векторную графику, хотя еще полгода назад были адептами символьных шрифтов (шучу, не такими уж и адептами). В статье я расскажу, с какими сложностями мы столкнулись в процессе, что из этого получилось, и почему вам стоит переходить на 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 — дизайнеру проекта.

Привет, Хабр!

Я сформулировал задачу так: сделать практичный набор пиктограмм. Только базовые иконки, нужные в обиходе большинства сайтов. Лупа — поиск, крестик — закрыть, вот это все. Второе ограничение: не выпендриваться с авторским стилем. Наоборот, пусть стиль иконок растворится в мейнстриме и так подойдет большинству.

Важный сосед — текст


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

  1. Набор стал крупнее. 16—24 пикселей сейчас, против 12—14 в прошлом.
  2. Шрифты стали разнообразнее. Прощай, Ариал.
  3. Благодаря экранам с высокой плотностью пикселей для основного текста стали чаще выбирать светлые начертания. Light и extra light соперничают с regular.



Источник: Smashing Magazine. Раздел Average Font Size For Body Copy за 2009 и 2013.


Для сайтов и приложений привычнее шрифты без засечек, поэтому исключаю антиквы. Итак, портрет: светлый гротеск большого размера. Выбираю Helvetica Neue Light — пусть на первых порах отдувается за все шрифты интернета.

А как же нормальные и полужирные начертания?

Нужно больше ограничений


Мы решили делать два стилистических набора: контурный и со сплошной заливкой. Первый годится для светлых шрифтов. Второй закроет насыщенности от нормальной до сверхжирной. Первый менее практичен, зато накладывает больше ограничений. Значит, с ним мы встретим и решим больше потенциальных проблем. С него и начнем.

Решение про два набора основано на давней идее про умные SVG-иконки, которые с помощью CSS можно подстроить под насыщенность и стиль шрифта. Здравым смыслом и экспериментами мы согнали с идеи лишний жир, который мог бы поглотить непредсказуемое количество времени, и сосредоточились на том, что способны сделать быстро.


Размер, оптика и четкость


Теперь нужно выбрать размер базовых квадрата и круга. Эти фигуры определят оптический вес каждой пиктограммы. Оптический вес — интересная штука. Если поставить рядом квадрат высотой 15 пикселей и круг такого же диаметра, то круг будет казаться меньше. Чтобы компенсировать эффект, круг нужно увеличить. Для нашего квадрата близким по оптическому весу будет круг диаметром 17 пикселей.


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

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


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

Возвращаюсь к исходной задаче: нужно найти такой размер базового круга, чтобы он сносно подходил к большинству популярных размеров основного текста. У меня три переменных: размер текста, диаметр круга и толщина штриха буквы. Перебирать их отношения вручную было лень и я запилил инструмент — лучше день потерять, потом за пять минут долететь. Разместил на странице надписи от 13 до 24 пикселей, рядом — базовый круг, прикрутил слайдер и принялся сравнивать.


Победил круг размером 17 пикселей. Контурный круг прошел мой ценз для надписей от 15 до 20 пикселей. Текст вне этого диапазона выглядит или тоньше контура иконки, или толще. Залитый круг, у которого нет ограничения на толщину штриха, подходит к надписям от 13 до 22 пикселей — дальше уже становится маловат.

Забавно, что в скрипте число 17 я поставил как значение по-умолчанию для диаметра. Знать бы сразу что угадал — сэкономил бы время :-)

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

Спасибо за внимание!

Проблемы, с которыми мы столкнулись


В момент написания гема я избавился от svgo в пользу малоизвестного svg_optimizer, написанного на Ruby. Впоследствии эта замена стала причиной появления зубцов при рендеринге иконок — оптимизатор чересчур старательно оптимизировал структуру SVG и дублировал код иконки. В результате вместо одной получались две, наложенные друг на друга.

После этого прокола svg_optimizer заменили на svgo, а у svgo отключили плагин mergePaths, портящий форму иконок.

Еще мы обернули иконку в дополнительный элемент, на это есть две причины. Первой проблемой стало нежелание jQuery менять классы SVG-элемента (с ванильным JS все работает отлично). А вторая проблема заключается в том, что события непосредственно на SVG-элементе не ловятся — нужно слушать их на обертке.

Из нерешаемого в данный момент: в Сафари контуры слегка «пожеваные».

Evil Icons


Мы сразу делали иконки по принципам разработки больших продуктов. Определяли целевую аудиторию и конкурентные преимущества. Проект изначально предполагался как свободный и бесплатный. Несмотря на это, мы спрашивали себя: если бы мы брали за иконки деньги, то что в них должно быть хорошего, чтобы человек согласился заплатить? Это помогало держать ум в тонусе и не отвлекаться на «просто прикольные фичи».

Мы сделали предварительный анонс и получили первую обратную связь. Благодаря ей буквально за пару дней иконки стали заметно лучше. Пользуясь случаем, благодарим всех, кто указывал на косяки и помогал их исправлять. Из-за вас, ребята, мы любим опенсорс, спасибо! :-)

Теперь настало время поделиться с хабражителями.

Представляем Evil Icons — набор бесплатных SVG-иконок для сайтов и веб-приложений. В комплекте: Node.js пакет и Ruby гем для разработчиков, файлы .ai и .sketch для дизайнеров.

evil-icons.io

Скоро выпустим дополнительные стили, дадим возможность добавлять в набор собственные иконки. Подумываем сделать плагины для Grunt и Gulp, а также подключение через CDN.

* * *

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

Бесспорно, у SVG свои проблемы. Однако, очень похоже, что ситуация будет выправляться. Браузеры будут все лучше поддерживать SVG, что видно уже сейчас. Экранов с высокой плотностью пикселей станет больше. Через пару лет, может быть, появятся мониторы с еще более высокой плотностью пикселей. Тем, кто работает с растром, придется готовить ассеты в @2x—@Nx и кто знает, насколько большим будет N.

Evil Icons — это самая доступная на текущий момент возможность перейти на SVG уже в вашем следующем проекте.
Tags:
Hubs:
+48
Comments55

Articles

Change theme settings