[Из песочницы] Векторная замена спрайтам — имплантируем SVG в CSS

Не так давно компания, в которой я работаю, наконец-то окончательно отказалась от поддержки IE8 и, как следствие, я вплотную занялся вопросом перехода с растровых иконок на векторные. Основные плюсы SVG — это масштабирование, малый вес и возможность стилизации через CSS.Сначала я попробовал воспользоваться техникой спрайтов, просто использовав вместо растра вектор, но тут возникло две проблемы:

Масштабирование. При произвольных размерах элементов спрайта для того, чтобы его точно отпозиционировать, приходится танцевать с бубном. И при изменении размера самого спрайта (например, при добавлении нового элемента) все может поползти. Возможность стилизации посредством CSS отсутствует, потому что физически SVG-картинки в HTML-коде нет. Тут я вспомнил про интеграцию картинок в CSS посредством кодирования оных base64 и использования data-uri. А с SVG все гораздо проще.Поскольку SVG-изображение — это XML-файл, то для него даже base64 не требуется, достаточно указать mime-тип как data: image/svg+xml и вставить содержимое SVG-файла одной строкой.Возьмем, к примеру, иконку корзины:

image

Ее код выглядит примерно так:

Соответственно, использование ее в качестве фона в data-uri будет выглядеть так: .element_whis_svg_background { background: url ('data: image/svg+xml; utf8, '); } Пробуем. В Хроме и Опере все замечательно, а вот в IE9–10–11, Safari, и, как ни странно, Firefox — фоновая картинка не отображается, они не понимают такой формат записи. Лезем искать, в чем проблема и выясняем, что для IE и прочих для содержимого SVG-файла надо выполнить URI-кодирование строки по стандарту RFC 3986. Кодируем, получаем вот такую конструкцию: %3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%201850%201635%22%3E%3Cg%20fill%3D%22%23101010%22%3E%3Cpath%20d%3D%22M1254%201163H51c-26%200–51–25–51–51V981c0–23%2022–51%2051–51h1075c22%200%2036–13%2044–30l96–192c4–9%201–12–8–12H51c-22%200–51–25–51–51V514c0–23%2023–51%2051–51h1298c27%200%2046–13%2056–33l200–401c9–18%2020–29%2041–29h182c19%200%2029%207%2018%2029l-554%201111c-5%2010–19%2023–38%2023z%22%2F%3E%3Ccircle%20cx%3D%22207%22%20cy%3D%221453%22%20r%3D%22181%22%2F%3E%3Ccircle%20cx%3D%221062%22%20cy%3D%221453%22%20r%3D%22181%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E Подставляем ее в background, проверяем: .element_whis_svg_background { background: url ('data: image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2 … svg%3E'); } Ура, все работает! Нюанс — кодировку в данном случае указывать не нужно. Если указать — то перестанет работать в IE.Ну и, наконец, для того, чтобы внешний вид иконки можно было настраивать, используем любой препроцессор (я использую LESS, но это не принципиально) и оформим наш класс иконки как примесь (mixin). Для того, чтобы можно было менять цвет заливки, находим в кодированной строке атрибут fill, там будет что-то типа:

fill%3D%22%23101010%22 То, что находится между %23 и %22 — и есть искомый код цвета, на место которого надо подставить переменную. В итоге получим следующее: .icon__cart (@width, @height, @fill) { content: ''; display: block; width: @width; height: @height; background-size: contain; background-repeat: no-repeat; background: url ('data: image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%201850%201635%22%3E%3Cg%20fill%3D%22%23@{fill}%22%3E%3Cpath%20d%3D%22M1254%201163H51c-26%200–51–25–51–51V981c0–23%2022–51%2051–51h1075c22%200%2036–13%2044–30l96–192c4–9%201–12–8–12H51c-22%200–51–25–51–51V514c0–23%2023–51%2051–51h1298c27%200%2046–13%2056–33l200–401c9–18%2020–29%2041–29h182c19%200%2029%207%2018%2029l-554%201111c-5%2010–19%2023–38%2023z%22%2F%3E%3Ccircle%20cx%3D%22207%22%20cy%3D%221453%22%20r%3D%22181%22%2F%3E%3Ccircle%20cx%3D%221062%22%20cy%3D%221453%22%20r%3D%22181%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E'); } Используется данная примесь следующим образом (образец произвольный): .block-whis-icon._cart { …;

&:: before { .icon__cart (30 px, 20 px, '1d9fbb'); …; } } Вот, собственно, и все. LESS- (SASS, Stylus, etc.) файлик с такими примесями отлично заменяет спрайт.Для оптимизации и кодирования SVG я использовал GULP, плагины gulp-svgo и gulp-data-uri-stream. Да, этот метод дает возможность менять лишь размеры иконки, цвет заливки и обводки, но в большинстве своем этого вполне достаточно.

© Habrahabr.ru