Статьи

«Reskinnable» SVG символы: как их создать (и почему)

SVG символы

Широкое распространение SVG на современных веб-страницах действительно выросло в 2016 году благодаря его размеру файла, масштабируемости и CSS.

Его можно использовать для систем значков (взгляните на « Построить свои собственные иконки SVG» ), хотя шрифты значков в некоторых случаях могут быть предпочтительнее (некоторая информация здесь: Великая дискуссия о значках: шрифты против SVG ).

Но SVG также можно использовать для логотипов или графических элементов (по крайней мере, не слишком сложных), а его естественная гибкость делает его идеальным решением для адаптивных сайтов (взгляните на статью Sara Soueidan « Создание SVG-адаптивных с помощью CSS» ).

Использование SVG позволяет нацеливать и изменять размер и цвет всего элемента с помощью CSS, но, если ваш код SVG не встроен в вашу HTML-страницу, вы не сможете изменить одну его часть таким образом .

Проблема

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

Та же форма SVG. Разные цвета.

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

Кроме того, есть ли способ сделать наше изображение символом SVG , чтобы использовать преимущества кэширования в браузере?

Я собираюсь обозначить это « Reskinnable SVG-символ» — «кости» вашего SVG-изображения остаются прежними, но легко изменить внешний вид поверхности.

Идеальным решением было бы получить доступ к символьным элементам через селектор CSS и добавить к ним некоторые правила (тот же метод, который мы использовали бы со встроенным SVG).

В следующем примере я добавил класс ( top , right , bottom и left ) к каждому треугольнику, расположил изображение как символ и попытался изменить его с помощью CSS следующим образом:

 .top { fill: #356BA5; } .right { fill: #357FD9; } /* and so on... */ 

К сожалению, на данный момент это работает только с Firefox, как показывает следующий Codepen. Второе изображение отображается в синих тонах только в Firefox (для удобства я ввел код символа в перо, но у нас те же результаты с внешними файлами SVG).

См. Редактирование элементов Pen svg (демонстрация 1) Массимо Кассандро ( @ massimo-cassandro ) на CodePen .

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

Моей целью было чистое CSS-решение: предыдущий пример можно переписать с помощью SVG с одним треугольником, который можно вращать, перемещать и раскрашивать с помощью CSS.

Но мне не понравилось это решение: мне кажется, что оно просто перемещает проблему, не решая ее. Сколько реальных логотипов имеют компоненты, которые имеют одинаковую форму?

Сара Соуэйдан объясняет проблему гораздо лучше, чем я, и предлагает нам умное решение с использованием переменных CSS . К сожалению, переменные CSS все еще являются экспериментальной технологией, и браузеры Microsoft их не поддерживают .

Решение

Как это часто бывает, решение настолько простое, что вы почувствуете себя глупо, не подумав об этом раньше.

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

qJVnVmr

Вы можете видеть, что логотип Medium состоит из четырех «фигур», каждая из которых имеет свой плоский цвет. Черно-белая версия идентична зеленой (кроме цвета, конечно).

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

Давайте применим его к нашему примеру и создадим символ для каждой фигуры на нашем изображении. Все они имеют один и тот же viewBox всего изображения ( 0 0 54 54 ), поэтому они помещают себя в правильное положение без каких-либо дополнительных инструкций. Просто позаботьтесь о том, чтобы в коде символа не использовались атрибуты fill , stroke , style и т. Д.).

 <svg xmlns="http://www.w3.org/2000/svg"> <symbol id="top" viewBox="0 0 54 54"> <polygon points="54 0 0 0 27 27 54 0"></polygon> </symbol> <symbol id="right" viewBox="0 0 54 54"> <polygon points="54 54 54 0 27 27 54 54"></polygon> </symbol> <symbol id="bottom" viewBox="0 0 54 54"> <polygon points="0 54 54 54 27 27 0 54"></polygon> </symbol> <symbol id="left" viewBox="0 0 54 54"> <polygon points="0 0 0 54 27 27 0 0"></polygon> </symbol> </svg> 

Теперь мы можем собрать их в один контейнер SVG:

 <svg> <use class="top" xlink:href="#top"></use> <use class="right" xlink:href="#right"></use> <use class="bottom" xlink:href="#bottom"></use> <use class="left" xlink:href="#left"></use> </svg> 

Каждый элемент use может быть стилизован так, как вам нравится, и, самое главное, он совместим со всеми современными браузерами:

Это все.

Мы просто должны расположить наши файлы SVG таким образом. Конечно, мы можем сделать это вручную, но если вам нужно управлять множеством графических элементов или вам нужно быстро редактировать и повторно использовать их в большем количестве проектов, вам нужен более умный и быстрый рабочий процесс. Я нашел свое решение, используя Adobe Illustrator и немного Gulp .

SVG Symbols создает рабочий процесс

Основы этой техники те же, что я только что описал в своих статьях « Создайте свои собственные SVG-иконки» и « Создайте шрифт- иконки» с помощью статей Illustrator и IcoMoon , так что посмотрите на них для первых шагов.

Скажем, у нас есть два элемента, как на картинке ниже. Каждый из них размещен в определенном артборде:

Иллюстратор артборд

Для удобства мы дали им немного цвета, хотя мы знаем, что цвет заливки (а также, если они есть, обводка, размер обводки и т. Д.) Будут редактироваться через CSS.

Поскольку у каждого символа должен быть свой артборд, теперь мы должны разделить каждое изображение на столько артбордов, сколько на каждой цветной части.

Это можно сделать очень быстро в Illustrator, обрезая каждый элемент, выбирая целевой артборд и выбирая команду « Вставить на месте» .

Иллюстратор артборд

Обратите внимание, что у каждого артборда есть свое имя: оно будет использоваться для идентификаторов символов.

Теперь мы можем экспортировать наши монтажные области в SVG, используя совершенно новую команду Файл → Экспорт → Экспорт для экранов .

Это действительно полезный новый инструмент в последних версиях Illustrator: он позволяет сохранять одну монтажную область или определенный пользователем ресурс во многих форматах с помощью одной команды.

Выберите «Artboards» на панели экспорта, установите «SVG» в качестве выходного формата и выберите папку назначения:

Экспорт символов

Каждый артборд будет экспортирован как один файл SVG:

SVG файлы

Теперь нам нужно собрать все файлы в виде символов SVG и удалить некоторые ненужные атрибуты SVG: небольшой скрипт gulp поможет нам сделать это очень быстро.

Время для глотка

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

Я уже писал о Gulp на SitePoint , и вы также можете найти в Интернете множество ресурсов об установке Gulp и обо всех связанных с этим аргументах, поэтому я предполагаю, что вы уже установили его и знаете, о чем мы говорим. около.

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

Итак, у нас есть несколько файлов SVG, каждый из которых расположен так же, как в примере ниже (атрибут d был сокращен для удобства):

 <svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" width="54" height="54" viewBox="0 0 54 54"> <title>umbrella-handle</title> <path d="..." fill="#603813"></path> </svg> 

Наша цель состоит в том, чтобы упорядочить все изображения в виде символов SVG в уникальном файле, удаляя при этом все нежелательные атрибуты:

 <svg xmlns="http://www.w3.org/2000/svg"> <symbol id="umbrella_handle" viewBox="0 0 54 54"> ... </symbol> <symbol id="umbrella_top" viewBox="0 0 54 54"> ... </symbol> <!-- and so on ... --> </svg> 

Помимо Gulp, наша работа нуждается в некоторых других расширениях:

  • Прежде всего, gulp-svgstore и gulp-svgmin для объединения и минимизации наших SVG-файлов.
  • Gulp-переименовать, чтобы настроить имена id и дать нашим файлам назначения конкретное имя. Этот модуль особенно необходим, если вы хотите использовать предыдущую команду экспорта в Illustrator SVG, мы рассмотрим ее позже.

Теперь мы можем организовать наш Gulpfile (код также доступен как публичный Gist ):

 var gulp = require('gulp') ,rename = require('gulp-rename') ,svgstore = require('gulp-svgstore') ,svgmin = require('gulp-svgmin') ; gulp.task('default', function() { gulp.src(['svg_files/*.svg']) .pipe(rename(function (path) { path.basename = path.basename.replace(/__icon_prefix__/, ''); return path; })) .pipe(svgmin(function (file) { return { // https://github.com/svg/svgo/tree/master/plugins plugins: [ { cleanupIDs: { remove: true, minify: true } } , { removeDoctype: true } , { removeComments: true } , { removeStyleElement: true } , { removeDimensions: true } , { cleanupNumericValues: { floatPrecision: 2 } } , { removeAttrs: { attrs: ['(fill|stroke|class|style)', 'svg:(width|height)'] } } ] //,js2svg: { pretty: true } // uncomment for readability }; })) .pipe(svgstore()) .pipe( rename('my-icons.svg') ) .pipe(gulp.dest('./')); }); 

После загрузки модулей мы указываем файлы, которые мы хотим проанализировать ( svg_files/*.svg ).

SVGstore использует имя каждого файла для установки атрибутов id символа (то есть файл с именем umbrella.svg станет символом с id="umbrella" ). Если вы используете новую панель « Экспорт в Illustrator для экранов» , вы можете избежать первой команды переименования , поскольку ваши файлы будут названы точно в том виде, в котором они отображаются.

Но в старых версиях Illustrator имена файлов создаются путем объединения имени файла Illustrator с именем артборда, поэтому нам нужно переименовать файлы, удалив префикс имени файла Illustrator:

 path.basename = path.basename.replace(/__icon_prefix__/, '') 

Теперь мы можем очистить наши файлы. gulp-svgmin — это версия SVGO для Gulp, «инструмент на основе Nodejs для оптимизации файлов векторной графики SVG» (Джейк Арчибальд выпустил онлайн-версию SVGO, которая действительно полезна, если вы хотите расположить файлы вручную).

SVGO имеет много настраиваемых параметров (вы можете просмотреть все из них на странице проекта), но нам нужно всего несколько (вы, конечно, можете настроить скрипт в соответствии со своими потребностями):

  • cleanupIDs : удаляет все идентификаторы из ваших файлов
  • removeDoctype , removeComments и removeStyleElement : removeStyleElement все комментарии removeStyleElement и элементы <style>
  • removeDimensions удаляет все атрибуты width и heights если присутствует viewbox
  • cleanupNumericValues округляет числовые значения до cleanupNumericValues уровня точности
  • removeAttrs удаляет все указанные атрибуты

Затем файлы передаются в svgstore для объединения в уникальный файл, который затем переименовывается и сохраняется.

После его использования несколько раз вы сможете организовать его за несколько минут для каждого проекта, и это даст вам возможность быстро перестроить файл SVG-символов в любое время.

Это пример результата (даже в эту ручку я для удобства встроил файл svg, но вы можете безопасно связать его как внешний файл):

См. Стилевое оформление Pen svg css (демонстрация 3) Массимо Кассандро ( @ massimo-cassandro ) на CodePen .

Есть ли какие-то предостережения?

Так как этот метод основан на стилевом use элементов, у нас возникают проблемы при их удалении полифилом, как мы видим в svg4everybody .

В браузерах, которые не поддерживают ссылку на внешние символы (все IE), svg4everybody заменяет все use элементы содержимым соответствующих символов. Таким образом, все правила CSS, которые применяются для use , не вступают в силу.

Это может быть решено path адаптации ваших CSS-селекторов к внутреннему элементу символов ( path , circle и т. Д.), Но это может быть немного сложнее.

Дополнительный бонус

Есть бесконечные варианты этого рабочего процесса: вы можете иметь дело с штрихами, текстом и т. Д.

Еще одна интересная особенность, которую необходимо изучить, — это использование символов Illustrator: они экспортируются как символы SVG, и это открывает множество возможностей.

Символы иллюстратора в скобках

Спасибо за прочтение.