Создаём и используем символьный SVG-спрайт

В данной статье посмотрим, как можно просто и быстро создавать и использовать символьные SVG-спрайты

'1'

Что такое SVG

SVG - масштабируемая векторная графика.

Сама по себе технология SVG - это очень объёмная тема - подробнее с ней можно познакомится на MDN Web Docs

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

Аналогичные иконки при масштабировании в формате SVG и PNG

'1'



Способы использования SVG-иконок

SVG-иконки можно использовать несколькими способами

1й способ - сохранить SVG-иконку как файл, и подключать как обычное изображение

<img src="img/github.svg" alt=""/>

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


2й способ - открыть файл SVG-иконки в текстовом редакторе, скопировать код иконки и вставить его в необходимую часть HTML.

<div class="icon">
  <svg xmlns="http://www.w3.org/2000/svg" width="64" height="64" shape-rendering="geometricPrecision" text-rendering="geometricPrecision" image-rendering="optimizeQuality" fill-rule="evenodd" clip-rule="evenodd" viewBox="0 0 640 640"><path d="M319.988 7.973C143.293 7.973 0 151.242 0 327.96c0 141.392 91.678 261.298 218.826 303.63 16.004 2.964 21.886-6.957 21.886-15.414 0-7.63-.319-32.835-.449-59.552-89.032 19.359-107.8-37.772-107.8-37.772-14.552-36.993-35.529-46.831-35.529-46.831-29.032-19.879 2.209-19.442 2.209-19.442 32.126 2.245 49.04 32.954 49.04 32.954 28.56 48.922 74.883 34.76 93.131 26.598 2.882-20.681 11.15-34.807 20.315-42.803-71.08-8.067-145.797-35.516-145.797-158.14 0-34.926 12.52-63.485 32.965-85.88-3.33-8.078-14.291-40.606 3.083-84.674 0 0 26.87-8.61 88.029 32.8 25.512-7.075 52.878-10.642 80.056-10.76 27.2.118 54.614 3.673 80.162 10.76 61.076-41.386 87.922-32.8 87.922-32.8 17.398 44.08 6.485 76.631 3.154 84.675 20.516 22.394 32.93 50.953 32.93 85.879 0 122.907-74.883 149.93-146.117 157.856 11.481 9.921 21.733 29.398 21.733 59.233 0 42.792-.366 77.28-.366 87.804 0 8.516 5.764 18.473 21.992 15.354 127.076-42.354 218.637-162.274 218.637-303.582 0-176.695-143.269-319.988-320-319.988l-.023.107z"/></svg>
</div>

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


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

Этот способ и рассмотрим подробнее



Создаём и используем символьный SVG-спрайт

Символьный SVG-спрайт - это просто коллекция символьных SVG-иконок, собранных в одном, обычно скрытом, специальном блоке

Для примера скачаем пару SVG-иконок, например, на сайте https://uxwing.com/ с бесплатными иконками

Чтобы автоматически создать SVG-спрайт, воспользуемся онлайн-сервисом https://svgsprit.es/

Просто перетаскиваем все необходимые файлы SVG-иконок на главную страницу https://svgsprit.es/, и внизу страницы автоматически будет сгенерирован код, состоящий из двух частей

Первая часть - символьный SVG спрайт

<svg width="0" height="0" class="hidden">
  <symbol xmlns="http://www.w3.org/2000/svg" shape-rendering="geometricPrecision" text-rendering="geometricPrecision" image-rendering="optimizeQuality" fill-rule="evenodd" clip-rule="evenodd" viewBox="0 0 640 640" id="twitter">
    <path d="M640.012 121.513c-23.528 10.524-48.875 17.516-75.343 20.634 27.118-16.24 47.858-41.977 57.756-72.615-25.347 14.988-53.516 25.985-83.363 31.866-24-25.5-58.087-41.35-95.848-41.35-72.508 0-131.21 58.736-131.21 131.198 0 10.228 1.134 20.232 3.355 29.882-109.1-5.528-205.821-57.757-270.57-137.222a131.423 131.423 0 00-17.764 66c0 45.497 23.102 85.738 58.347 109.207-21.508-.638-41.74-6.638-59.505-16.359v1.642c0 63.627 45.225 116.718 105.32 128.718-11.008 2.988-22.63 4.642-34.606 4.642-8.48 0-16.654-.874-24.78-2.35 16.783 52.11 65.233 90.095 122.612 91.205-44.989 35.245-101.493 56.233-163.09 56.233-10.63 0-20.988-.65-31.334-1.89 58.229 37.359 127.206 58.997 201.31 58.997 241.42 0 373.552-200.069 373.552-373.54 0-5.764-.13-11.35-.366-16.996 25.642-18.343 47.87-41.493 65.469-67.844l.059-.059z"></path>
  </symbol>
  <symbol xmlns="http://www.w3.org/2000/svg" shape-rendering="geometricPrecision" text-rendering="geometricPrecision" image-rendering="optimizeQuality" fill-rule="evenodd" clip-rule="evenodd" viewBox="0 0 640 640" id="github">
    <path d="M319.988 7.973C143.293 7.973 0 151.242 0 327.96c0 141.392 91.678 261.298 218.826 303.63 16.004 2.964 21.886-6.957 21.886-15.414 0-7.63-.319-32.835-.449-59.552-89.032 19.359-107.8-37.772-107.8-37.772-14.552-36.993-35.529-46.831-35.529-46.831-29.032-19.879 2.209-19.442 2.209-19.442 32.126 2.245 49.04 32.954 49.04 32.954 28.56 48.922 74.883 34.76 93.131 26.598 2.882-20.681 11.15-34.807 20.315-42.803-71.08-8.067-145.797-35.516-145.797-158.14 0-34.926 12.52-63.485 32.965-85.88-3.33-8.078-14.291-40.606 3.083-84.674 0 0 26.87-8.61 88.029 32.8 25.512-7.075 52.878-10.642 80.056-10.76 27.2.118 54.614 3.673 80.162 10.76 61.076-41.386 87.922-32.8 87.922-32.8 17.398 44.08 6.485 76.631 3.154 84.675 20.516 22.394 32.93 50.953 32.93 85.879 0 122.907-74.883 149.93-146.117 157.856 11.481 9.921 21.733 29.398 21.733 59.233 0 42.792-.366 77.28-.366 87.804 0 8.516 5.764 18.473 21.992 15.354 127.076-42.354 218.637-162.274 218.637-303.582 0-176.695-143.269-319.988-320-319.988l-.023.107z"></path>
  </symbol>
</svg>

Вторая часть - код использования

<svg class="icon">
  <use xlink:href="#twitter"></use>
</svg>
<svg class="icon">
  <use xlink:href="#github"></use>
</svg>


Создадим HTML разметку, в которую добавим сгенерированный символьный SVG-спрайт и сразу используем иконки в необходимых местах

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8"/>
    <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
    <title>SVG</title>
    <link rel="stylesheet" href="css/bootstrap-reboot.min.css"/>
    <link rel="stylesheet" href="css/main.css"/>
  </head>
  <body>
    <section class="icons">
      <div class="container">
        <div class="icons__flex">
          <div class="icons__icon">
            <!-- Используем иконку Twitter -->
            <svg class="icon">
              <use xlink:href="#twitter"></use>
            </svg>
          </div>
          <div class="icons__icon">
            <!-- Используем иконку Github -->
            <svg class="icon">
              <use xlink:href="#github"></use>
            </svg>
          </div>
        </div>
      </div>
    </section>

    <!-- Скрытый SVG-спрайт -->
    <svg class="hidden" width="0" height="0">

      <!-- Иконка Twitter в SVG-спрайте-->
      <symbol id="twitter" xmlns="http://www.w3.org/2000/svg" shape-rendering="geometricPrecision" text-rendering="geometricPrecision" image-rendering="optimizeQuality" fill-rule="evenodd" clip-rule="evenodd" viewbox="0 0 640 640">
        <path d="M640.012 121.513c-23.528 10.524-48.875 17.516-75.343 20.634 27.118-16.24 47.858-41.977 57.756-72.615-25.347 14.988-53.516 25.985-83.363 31.866-24-25.5-58.087-41.35-95.848-41.35-72.508 0-131.21 58.736-131.21 131.198 0 10.228 1.134 20.232 3.355 29.882-109.1-5.528-205.821-57.757-270.57-137.222a131.423 131.423 0 00-17.764 66c0 45.497 23.102 85.738 58.347 109.207-21.508-.638-41.74-6.638-59.505-16.359v1.642c0 63.627 45.225 116.718 105.32 128.718-11.008 2.988-22.63 4.642-34.606 4.642-8.48 0-16.654-.874-24.78-2.35 16.783 52.11 65.233 90.095 122.612 91.205-44.989 35.245-101.493 56.233-163.09 56.233-10.63 0-20.988-.65-31.334-1.89 58.229 37.359 127.206 58.997 201.31 58.997 241.42 0 373.552-200.069 373.552-373.54 0-5.764-.13-11.35-.366-16.996 25.642-18.343 47.87-41.493 65.469-67.844l.059-.059z"></path>
      </symbol>

      <!-- Иконка Github в SVG-спрайте-->
      <symbol id="github" xmlns="http://www.w3.org/2000/svg" shape-rendering="geometricPrecision" text-rendering="geometricPrecision" image-rendering="optimizeQuality" fill-rule="evenodd" clip-rule="evenodd" viewbox="0 0 640 640">
        <path d="M319.988 7.973C143.293 7.973 0 151.242 0 327.96c0 141.392 91.678 261.298 218.826 303.63 16.004 2.964 21.886-6.957 21.886-15.414 0-7.63-.319-32.835-.449-59.552-89.032 19.359-107.8-37.772-107.8-37.772-14.552-36.993-35.529-46.831-35.529-46.831-29.032-19.879 2.209-19.442 2.209-19.442 32.126 2.245 49.04 32.954 49.04 32.954 28.56 48.922 74.883 34.76 93.131 26.598 2.882-20.681 11.15-34.807 20.315-42.803-71.08-8.067-145.797-35.516-145.797-158.14 0-34.926 12.52-63.485 32.965-85.88-3.33-8.078-14.291-40.606 3.083-84.674 0 0 26.87-8.61 88.029 32.8 25.512-7.075 52.878-10.642 80.056-10.76 27.2.118 54.614 3.673 80.162 10.76 61.076-41.386 87.922-32.8 87.922-32.8 17.398 44.08 6.485 76.631 3.154 84.675 20.516 22.394 32.93 50.953 32.93 85.879 0 122.907-74.883 149.93-146.117 157.856 11.481 9.921 21.733 29.398 21.733 59.233 0 42.792-.366 77.28-.366 87.804 0 8.516 5.764 18.473 21.992 15.354 127.076-42.354 218.637-162.274 218.637-303.582 0-176.695-143.269-319.988-320-319.988l-.023.107z"></path>
      </symbol>

    </svg>

  </body>
</html>


Добавим стили

Прежде чем задавать цвет иконки в CSS, необходимо убедиться, что у кода иконки в SVG-спрайте отсутствуют свойства fill и stroke. Если эти свойства присутсвуют в коде иконки, то необходимо их удалить, так как приоритет CSS свойств будет ниже, чем у inline-стилей, и значения, указанные в CSS будут игнорироваться

Чтобы через CSS задать цвет для SVG-иконки, используем свойства fill и stroke

fill - заливка иконки

stroke - цвет обводки

Если иконка состоит только из обводки, то чаще всего для свойства fill необходимо указать значение transparent, чтобы у иконки не было чёрной заливки по-умолчанию

body {
  background: #121212;
}
.container {
  max-width: 1140px;
  margin: 0 auto;
}
.icons {
  padding: 64px 0;
}
.icons__flex {
  display: flex;
  align-items: center;
  justify-content: center;
}
.icons__icon:not(:last-child) {
  margin-right: 24px;
}
.icons__icon svg.icon {
  width: 64px; /* ширина иконки */
  height: 64px; /* высота иконки */
  fill: #3626a7; /* цвет заливки иконки */
  transition: 0.25s; /* плавное изменение цвета при наведении */
}
.icons__icon:hover svg.icon {
  fill: #422ecc; /* цвет заливки иконки при наведении */
}

/* Скрываем блок SVG-спрайта */
.hidden {
  display: none;
}


Получаем следующий результат




Итоги

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

В статье рассмотрели как быстро и просто создать символьный SVG-спрайт и оптимально использовать SVG-иконки

Буду рад, если статья оказалась полезной

Спасибо за ваше внимание и уделённое время!