SVG заметки
Некоторые заметки по работе с <svg>
которые вы возможно не знаете и которые будут полезны.
Ресурсы
Иконки (бесплатные):
- https://blade-ui-kit.com/blade-icons - 75 000 иконок.
- https://fonts.google.com/icons
- https://icons8.ru/icons
- https://useiconic.com/open
- https://icomoon.io/app - можно собрать спрайт.
URL-encoder:
Оптимизация SVG:
Векторизация (Картинка → SVG):
- https://www.vectorizer.io/ - результат можно забрать так.
Обязательно ли использовать атрибут xmlns="http://www.w3.org/2000/svg"?
В половине примеров svg, которые я вижу в Интернете, код обернут в простые теги <svg></svg>. В другой половине теги svg имеют множество атрибутов, например:
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" >
Какие из атрибутов svg действительно нужны?
-
Если вы встраиваете svg код прямо в HTML и при отдаче HTML указан заголовок
text/html
, то атрибуты xmlns можно не указывать.Однако если при отдаче HTML, в который встроен svg код, вы указывает другой тип (заголовок ответа) например
image/svg+xml
,application/xhtml+xml
или любой другой, который заставляет пользовательский агент использовать парсер XML, то атрибуты xmlns обязательны!Заметка: Встраивание SVG в HTML-документы стало возможно в HTML5.
Подробнее: https://stackoverflow.com/questions/18467982/are-svg-parameters-such-as-xmlns-and-version-needed
- Все браузеры игнорируют атрибут
version
, поэтому вы всегда можете отказаться от него.
Как наследовать цвет родительского элемента в svg
Есть несколько SVG-изображений, которые нужно вставить в HTML-страницу, стилизованную с помощью CSS. Нужно, чтобы элементы SVG унаследовали цвет от атрибута color
родительского HTML-элемента. Варианты: style="fill: inherit"
или fill="inherit"
не работают.
Проблема тут в том, что HTML использует color, а SVG использует fill и stroke.
Чтобы взять цвет у родительского элемента, можно заставить fill и stroke использовать значение свойства color из CSS. Для этого в CSS есть специальное значение currentColor
. fill понимает это значение:
<svg ... fill="currentColor">
ВАЖНО: этот прием будет работать только если SVG встраивается в сам HTML код, а не подключается как файл. Потому что код файла инкапсулирован в самом файле и ничего не знает о внешних данных, а значит currentColor у него ни на что не ссылается.
Поддержка Браузерами:
SVG спрайты
node.js библиотека для создания спрайтов: https://github.com/svg-sprite/svg-sprite
Спрайты позволяют объединить несколько svg кодов в один. И затем обращаться к отдельной иконке (svg) не добавляя весь код svg повторно в HTML.
Как создавать спрайт?
Допустим у нас есть две svg иконки:
<svg height="24px" width="24px" viewBox="0 0 24 24" fill="currentColor"> <path d="M19 13H5v-2h14v2z"/> </svg>
<svg height="24px" width="24px" viewBox="0 0 24 24" fill="currentColor"> <path d="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/> </svg>
Чтобы из них сделать спрайт, нужно:
-
Создать svg элемент (контейнер).
<svg style="display: none;" aria-hidden="true"> </svg>
-
Заменить в исходном коде svg на symbol. А также, добавить атрибут id (по нему в дальнейшем будем обращаться к svg).
Этот код:
<svg height="24px" width="24px" viewBox="0 0 24 24" fill="currentColor"> <path d="M19 13H5v-2h14v2z"/> </svg>
Переварится в:
<symbol id="minus" height="24px" width="24px" viewBox="0 0 24 24" fill="currentColor"> <path d="M19 13H5v-2h14v2z"/> </symbol>
-
Поместить symbol в контейнер (в спрайт).
<svg style="display: none;"> <symbol id="minus" height="24px" width="24px" viewBox="0 0 24 24" fill="currentColor"> <path d="M19 13H5v-2h14v2z"/> </symbol> <symbol id="plus" height="24px" width="24px" viewBox="0 0 24 24" fill="currentColor"> <path d="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/> </symbol> </svg>
Теперь можно добавить этот код в HTML, а затем выводить отдельную иконку обращаясь к ней по id:
<svg height="50" width="50"><use xlink:href="#minus"></use></svg>
Или можно создать из этого кода файл, например, sprite.svg
и также выводить отдельную иконку обращаясь к ней по id:
<svg height="50" width="50"><use xlink:href="/sprite.svg#minus"></use></svg>
Разница в этих двух подходах, помимо прочего:
-
Когда мы добавляем svg в HTML код страницы, спрайт становится частью DOM дерева и поэтому элементам спрайта можно указать цвет через css или они могут наследовать цвет от родительского элемента - благодаря атрибуту fill="currentColor".
- А когда, спрайт подключается как файл, файл является внешним элементом и поэтому его элементы никак не связаны с текущим DOM деревом, и им невозможно задать цвет через css или наследовать цвет от родителей.
Поэтому, спрайт лучше подключать прямо в HTML, особенно если спрайт небольшой. Также важно скрыть контейнер, чтобы браузер не пытался его отрисовать. Сделать это можно добавив style="display: none;"
к контейнеру.
<svg style="display: none;" aria-hidden="true"> <symbol id="minus" viewBox="0 0 24 24" fill="currentColor"> <path d="M19 13H5v-2h14v2z"/> </symbol> </svg>
Более навороченная конструкция контейнера, которая предлагается в интернете, в чем её преимущества я не разбирался, но возможно лучше использовать её:
<svg aria-hidden="true" style="position: absolute; width: 0; height: 0; overflow: hidden;" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" > <defs> <symbol ...> <symbol ...> <symbol ...> </defs> </svg>
Свойство stroke-dasharray
Определяет структуру штрихов и пробелов, используемых для рисования контура фигуры.
Атрибут stroke-dasharray
может быть использован в качестве CSS свойства.
Синтаксис:
// SVG (HTML) атрибут stroke-dasharray="none | [dasharray]"
// CSS stroke-dasharray: none | [dasharray];
- [dasharray]
Список чисел задающих длину тире и длину пробела. Указывается через запятые или пробелы.
stroke-dasharray="3 1"; // 3 длина тире, 1 длина пробела stroke-dasharray="3 1, 2 1"; // 3 длина тире, 1 длина пробела, 2 тире, 1 пробел
Можно указать процентные значения:
stroke-dasharray="3 1%"
Если задано нечетное количество значений, то список значений повторяется, чтобы получить четное количество значений. Так
5 3 2
превратиться в5 3 2 5 3 2
:stroke-dasharray="5 3, 2" // превратиться в stroke-dasharray="5 3, 2 5, 3 2"
Документация stroke-dasharray: https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-dasharray
Пример:
<svg viewBox="0 0 30 10" stroke="tomato" style="width: 10em;"> <!-- No dashes nor gaps --> <line x1="0" y1="1" x2="30" y2="1" /> <!-- Dashes and gaps of the same size --> <line stroke-dasharray="4" x1="0" y1="3" x2="30" y2="3"/> <!-- Dashes and gaps of different sizes --> <line stroke-dasharray="4 1" x1="0" y1="5" x2="30" y2="5"/> <!-- Dashes and gaps of various sizes with an odd number of values --> <line stroke-dasharray="4 1, 2" x1="0" y1="7" x2="30" y2="7"/> <!-- Dashes and gaps of various sizes with an even number of values --> <line stroke-dasharray="4 1, 2 3" x1="0" y1="9" x2="30" y2="9"/> </svg>
Получим:
Пример Круговой диаграммы (pie-chart) на SVG с помощью свойства stroke-dasharray:
Еще примеры на codepen: https://codepen.io/tag/stroke-dasharray
Встраивание SVG в CSS
Иногда возникает необходимость вставить SVG-картинку инлайном как значение какого-нибудь свойства в CSS.
Например, иконки как фоновые картинки:
background-image: url('data:image/svg+xml;base64,A1B2...C3=')
Стоян Стефанов напоминает, что почти все браузеры (кроме старых вроде IE), нуждаются в кодировании всего 3 символов: <
, >
и #
. Поэтому делать полноценный base64 не нужно — это не читаемо, не редактируемо, раздувает бандл. Дайте gzip делать его работу.
У Юли Бухваловой есть готовый инструмент под такое:
https://yoksel.github.io/url-encoder/ - преобразует большее количество символов, но зато более надёжно.
Читайте по теме: https://www.phpied.com/truth-encoding-svg-data-uris/