[Из песочницы] Спойлер: Вставка SVG иконок одним единственным способом

imageВ статье будет обсуждаться проблема вставки SVG иконок в веб — страницу.

Что мы имеем, и как мы используем это. Глобально есть три способа:

  • Вставка исходного кода SVG иконки прямо в DOM страницы.
  • С помощью HTML тега IMG
  • С помощью CSS background-image


Мы не будем говорить о варианте вставки иконок в виде шрифтов, ибо у этого подхода есть масса недостатков (некоторые из них чисто субъективны), о которых можно узнать с помощью поиска в Гугл, и вариант с IFRAME и OBJECT тегами тоже опустим по той же причине.
У всех этих способов есть свои достоинства и недостатки. С появлением SVG у нас появились новые требования к иконкам. Например, во времена PNG нам и в голову бы не пришло использовать одну и ту же иконку в разных размерах в разных частях сайта и с разными цветными заливками. Для этого нам пришлось бы попросить у дизайнера несколько иконок с разными цветами и размерами. Но с появлением SVG мы озверели и начали одну и ту же иконку вставлять повсюду, так как появилась возможность в соответствии с желаниями изменять вид иконки с помощью CSS.

Приведу пример:
Есть у нас иконка — звездочка для рейтингов. Где-то она белая, где-то желтая, большая и маленькая. Плюс может быть обрезанная половинка звездочки, скажем, для обозначения рейтинга 2.5 или 4+.

Для реализации данного примера нам нужно как минимум четыре PNG иконок для каждого цвета и формы, но если у нас SVG, то вместо четырех мы спокойно можем обойтись и одной единственной, специально оформленной для данной задачи и не только.

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

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

А что насчет второго варианта, то он самый избыточный, так как не имеет ни одного из достоинств двух других вариантов.

Что у нас получается? Мы имеем два варианта вставки иконок, у которых есть свои достоинства и между которыми иногда бывает сложно сделать выбор.

А теперь представьте, что вы можете использовать почти все достоинства (кроме анимации отдельных частей иконки) первого варианта наряду с третьим вариантом.

То есть вставлять иконки с помощью CSS background-image, или HTML тега IMG, и по вашему усмотрению изменить цвет каждого тега в SVG, будь то path, polygon или circle, не имеет значения.

Вот как это будет выглядеть:

background-image: url(star.svg?p=red,$00ff00,,green);


или




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

Тут ссылка того, как я решил для себя эту проблему. Приветствуются любые решения, если они крутые.

Как это работает


Структура директорий
  • caches — папка для кэша
  • colors — папка для хранения оригинальных цветов иконок
  • icons — папка для отформатированных иконок
  • originals — папка, куда скачиваются все иконки (ее можно задать и вручную)


Цикл работы

Берутся все иконки из папки originals, с помощью DOMDocument находятся все теги иконок, у которых есть цвет (fill), после цвет в иконке заменяется указателем на него в виде этого — »%1», а оригинальный цвет мы сохраняем в папке colors для случая, если мы захотим, чтобы она осталась неизменной.

Пример использования данной реализации.

icon/?p=parse /* запускает цикл работы */

icon/?p=empty /* удаляет все файлы, созданные вследствии работы команды parse */

background-image: url("icon/?p=leaderboard,red,blue,$000,green,orange,yellow,$0f0");


image

background-image: url("icon/?p=leaderboard,red,blue,$000");


image

background-image: url("icon/?p=leaderboard,,blue,$000,orange,red");


image

background-image: url("icon/?p=history");


image

background-image: url("icon/?p=history,$ff0000");


image

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

P.S.: Пока что не успел на продакщене использовать, сижу гадаю, что можно еще подправить, или с какими проблемами можно столкнутся с этим, так что приветствуется любая критика, заранее спасибо.

© Habrahabr.ru