Svg sprite — посібник з роботи зі svg спрайтами. Генерація спрайтів за допомогою gulp
RU
UK

Svg спрайти

07 Листопада 2021 р.
Зміст

Всім привіт! У цій статті ми розглянемо роботу зі svg спрайтами, як їх створювати та підключати. Спочатку розберемося що таке спрайт. Спрайт – це один великий графічний файл, у якому поєднано кілька невеликих зображень. Спрайти були дуже популярні, коли в якості графіки використовували растрові зображення. Створювали один великий файл, який містить іконки, смайлики, логотипи, після чого через фонове зображення CSS та позиціонування показували тільки ту частину графіки, яка необхідна. Це робиться для зменшення кількості запитів на сервер, тим самим збільшуючи швидкість завантаження сайту. Svg спрайт аналогічний: у ньому всі наші svg зображення зашиті в один файл. Але працювати з ним треба трохи інакше.

Як зробити svg спрайт

Щоб створити svg спрайт, створюємо svg файл, наприклад, sprite.svg. У нього помістимо кореневий елемент svg. Далі вставляємо код svg кожного зображення, обрамляючи його тегом symbol. Всім елементам symbol призначаємо унікальний ID:

<svg>

    <symbol viewBox="0 0 448 512" id="icon1">
        {/* Иконка 1 */}
    </symbol>

    <symbol viewBox="0 0 448 512" id="icon2">
        {/* Иконка 2 */}
    </symbol>

    <symbol viewBox="0 0 448 512" id="icon3">
       {/* Иконка 3 */}
    </symbol>

</svg>

Як використовувати svg спрайти

Щоб вивести будь-яку іконку зі svg спрайту, необхідно використовувати тег svg, в якому через конструкцію use вказуємо посилання на файл і id зображення:

<svg>
<use xlink:href="/sprite.svg#icon1"></use>
</svg>

Також можна просто скопіювати увесь svg спрайт в html сторінку і використовувати елемент use, передаючи тільки id зображення.

CSS стилі у svg спрайтах

Основною перевагою використання svg спрайт є можливість стилізувати іконки через CSS стилі. Ми можемо змінювати розмір, колір, фон іконок, а також змінювати стилі при наведенні. Для цього в спрайте необхідно видалити атрибути fill, stroke, style, оскільки вони мають великий пріоритет. Далі просто в CSS задавати стилі svg елемента.

Приклад використання svg спрайту

Давайте для прикладу використання svg спрайтів зробимо блок із іконками соціальних мереж. Скачаємо три svg іконки та зробимо з них спрайт. У результаті отримаємо:

<svg>
        <symbol viewBox="0 0 448 512" id="instagram">
            <path d="M224.1 141c-63.6 0-114.9 51.3-114.9 114.9s51.3 114.9 114.9 114.9S339 319.5 339 255.9 287.7 141 224.1 141zm0 189.6c-41.1 0-74.7-33.5-74.7-74.7s33.5-74.7 74.7-74.7 74.7 33.5 74.7 74.7-33.6 74.7-74.7 74.7zm146.4-194.3c0 14.9-12 26.8-26.8 26.8-14.9 0-26.8-12-26.8-26.8s12-26.8 26.8-26.8 26.8 12 26.8 26.8zm76.1 27.2c-1.7-35.9-9.9-67.7-36.2-93.9-26.2-26.2-58-34.4-93.9-36.2-37-2.1-147.9-2.1-184.9 0-35.8 1.7-67.6 9.9-93.9 36.1s-34.4 58-36.2 93.9c-2.1 37-2.1 147.9 0 184.9 1.7 35.9 9.9 67.7 36.2 93.9s58 34.4 93.9 36.2c37 2.1 147.9 2.1 184.9 0 35.9-1.7 67.7-9.9 93.9-36.2 26.2-26.2 34.4-58 36.2-93.9 2.1-37 2.1-147.8 0-184.8zM398.8 388c-7.8 19.6-22.9 34.7-42.6 42.6-29.5 11.7-99.5 9-132.1 9s-102.7 2.6-132.1-9c-19.6-7.8-34.7-22.9-42.6-42.6-11.7-29.5-9-99.5-9-132.1s-2.6-102.7 9-132.1c7.8-19.6 22.9-34.7 42.6-42.6 29.5-11.7 99.5-9 132.1-9s102.7-2.6 132.1 9c19.6 7.8 34.7 22.9 42.6 42.6 11.7 29.5 9 99.5 9 132.1s2.7 102.7-9 132.1z"></path>
        </symbol>

        <symbol viewBox="0 0 448 512" id="facebook">
            <path d="m279.14 288 14.22-92.66h-88.91v-60.13c0-25.35 12.42-50.06 52.24-50.06h40.42V6.26S260.43 0 225.36 0c-73.22 0-121.08 44.38-121.08 124.72v70.62H22.89V288h81.39v224h100.17V288z"/>
        </symbol>

        <symbol viewBox="0 0 448 512" id="twitter">
           <path d="M459.37 151.716c.325 4.548.325 9.097.325 13.645 0 138.72-105.583 298.558-298.558 298.558-59.452 0-114.68-17.219-161.137-47.106 8.447.974 16.568 1.299 25.34 1.299 49.055 0 94.213-16.568 130.274-44.832-46.132-.975-84.792-31.188-98.112-72.772 6.498.974 12.995 1.624 19.818 1.624 9.421 0 18.843-1.3 27.614-3.573-48.081-9.747-84.143-51.98-84.143-102.985v-1.299c13.969 7.797 30.214 12.67 47.431 13.319-28.264-18.843-46.781-51.005-46.781-87.391 0-19.492 5.197-37.36 14.294-52.954 51.655 63.675 129.3 105.258 216.365 109.807-1.624-7.797-2.599-15.918-2.599-24.04 0-57.828 46.782-104.934 104.934-104.934 30.213 0 57.502 12.67 76.67 33.137 23.715-4.548 46.456-13.32 66.599-25.34-7.798 24.366-24.366 44.833-46.132 57.827 21.117-2.273 41.584-8.122 60.426-16.243-14.292 20.791-32.161 39.308-52.628 54.253z"/>
        </symbol>    
    </svg>

Далі створюємо html файл і робимо в ньому невелику розмітку для виведення іконок. Після цього копіюємо вміст svg спрайту. У результаті отримуємо таку розмітку:

<body>
    <ul class="social">
        <li class="social__item">
            <a href="" class="social__link">
                <svg class="social__icon">
                    <use xlink:href="#instagram"></use>
                </svg>
            </a>
        </li>
        <li class="social__item">
            <a href="" class="social__link">
                <svg class="social__icon">
                    <use xlink:href="#facebook"></use>
                </svg>
            </a>
        </li>
        <li class="social__item">
            <a href="" class="social__link">
                <svg class="social__icon">
                    <use xlink:href="#twitter"></use>
                </svg>
            </a>
        </li>
    </ul>

    <svg>
        <symbol viewBox="0 0 448 512" id="instagram">
            <path d="M224.1 141c-63.6 0-114.9 51.3-114.9 114.9s51.3 114.9 114.9 114.9S339 319.5 339 255.9 287.7 141 224.1 141zm0 189.6c-41.1 0-74.7-33.5-74.7-74.7s33.5-74.7 74.7-74.7 74.7 33.5 74.7 74.7-33.6 74.7-74.7 74.7zm146.4-194.3c0 14.9-12 26.8-26.8 26.8-14.9 0-26.8-12-26.8-26.8s12-26.8 26.8-26.8 26.8 12 26.8 26.8zm76.1 27.2c-1.7-35.9-9.9-67.7-36.2-93.9-26.2-26.2-58-34.4-93.9-36.2-37-2.1-147.9-2.1-184.9 0-35.8 1.7-67.6 9.9-93.9 36.1s-34.4 58-36.2 93.9c-2.1 37-2.1 147.9 0 184.9 1.7 35.9 9.9 67.7 36.2 93.9s58 34.4 93.9 36.2c37 2.1 147.9 2.1 184.9 0 35.9-1.7 67.7-9.9 93.9-36.2 26.2-26.2 34.4-58 36.2-93.9 2.1-37 2.1-147.8 0-184.8zM398.8 388c-7.8 19.6-22.9 34.7-42.6 42.6-29.5 11.7-99.5 9-132.1 9s-102.7 2.6-132.1-9c-19.6-7.8-34.7-22.9-42.6-42.6-11.7-29.5-9-99.5-9-132.1s-2.6-102.7 9-132.1c7.8-19.6 22.9-34.7 42.6-42.6 29.5-11.7 99.5-9 132.1-9s102.7-2.6 132.1 9c19.6 7.8 34.7 22.9 42.6 42.6 11.7 29.5 9 99.5 9 132.1s2.7 102.7-9 132.1z"></path>
        </symbol>

        <symbol viewBox="0 0 448 512" id="facebook">
            <path d="m279.14 288 14.22-92.66h-88.91v-60.13c0-25.35 12.42-50.06 52.24-50.06h40.42V6.26S260.43 0 225.36 0c-73.22 0-121.08 44.38-121.08 124.72v70.62H22.89V288h81.39v224h100.17V288z"/>
        </symbol>

        <symbol viewBox="0 0 448 512" id="twitter">
           <path d="M459.37 151.716c.325 4.548.325 9.097.325 13.645 0 138.72-105.583 298.558-298.558 298.558-59.452 0-114.68-17.219-161.137-47.106 8.447.974 16.568 1.299 25.34 1.299 49.055 0 94.213-16.568 130.274-44.832-46.132-.975-84.792-31.188-98.112-72.772 6.498.974 12.995 1.624 19.818 1.624 9.421 0 18.843-1.3 27.614-3.573-48.081-9.747-84.143-51.98-84.143-102.985v-1.299c13.969 7.797 30.214 12.67 47.431 13.319-28.264-18.843-46.781-51.005-46.781-87.391 0-19.492 5.197-37.36 14.294-52.954 51.655 63.675 129.3 105.258 216.365 109.807-1.624-7.797-2.599-15.918-2.599-24.04 0-57.828 46.782-104.934 104.934-104.934 30.213 0 57.502 12.67 76.67 33.137 23.715-4.548 46.456-13.32 66.599-25.34-7.798 24.366-24.366 44.833-46.132 57.827 21.117-2.273 41.584-8.122 60.426-16.243-14.292 20.791-32.161 39.308-52.628 54.253z"/>
        </symbol>    
    </svg>
</body>

Тепер додамо трохи стилів:

body{
    background-color: #333;
}
.social {
    display: flex;
    justify-content: space-between;
    background-color: #fff;
    list-style-type: none;
    width: 300px;
    padding: 10px 20px 10px 20px;
    margin: 0 auto;
    border-radius: 30px;
}
.social__link {
    fill: #333;
}
.social__link:hover{
    fill: #E67E22;
}
.social__icon{
    fill: inherit;
    height: 60px;
    width: 60px;
    transition: .2s;
}

Тут ми вирівнюємо наші іконки по горизонталі, задаємо розміри та кольори. Колір іконки у звичайному стані і при наведенні задаємо за допомогою властивості fill батьківському елементу, а у самої іконки успадковуємо цю властивість. Таким чином отримуємо таку верстку:

See the Pen Svg sprite by astupakov (@astupakov) on CodePen.

Використання gulp для автоматичної генерації svg спрайтів

Збирати спрайти вручну – дуже трудомістка робота. Тому створення svg спрайтів можна автоматизувати. Для цього ми будемо використовувати gulp та плагін gulp-svg-sprite.

Ідея полягає в тому, що ми просто переміщаємо всі свої svg файли в одну папку, а gulp захопить усі ці файли та згенерує спрайт автоматично. Розглянемо коротко як це реалізувати.

Встановлюємо плагін gulp-svg-sprite:

npm install gulp-svg-sprite –S

У файлі gulpfile.js створюємо таск для генерації спрайту:

const gulp = require('gulp');
const svgSprite = require('gulp-svg-sprite');

function svgsprite(){
    let config = {
        shape: {
            dimension: {
                maxWidth: 500,
                maxHeight: 500
            },
            spacing: {
                padding: 0
            },
            transform: [{
                "svgo": {
                    "plugins": [
                        { removeViewBox: false },
                                { removeUnusedNS: false },
                                { removeUselessStrokeAndFill: true },
                                { cleanupIDs: false },
                                { removeComments: true },
                                { removeEmptyAttrs: true },
                                { removeEmptyText: true },
                                { collapseGroups: true },
                                { removeAttrs: { attrs: '(fill|stroke|style)' } }
                    ]
                }
            }]
        },
        mode: {
            symbol: {
                dest : '.',
                sprite: 'sprite.svg'
            }
        }
    };

    return gulp.src("src/img/svgIcons/*.svg")      
        .pipe(svgSprite(config)).on('error', function(error){ console.log(error); })
        .pipe(gulp.dest("dist/img/ "));
}

exports.svgsprite = svgsprite;

На початку ми створюємо змінну config з налаштуваннями для плагіна, в якій говоримо, що спрайт створюватиметься через елемент symbol і називається spite.svg. Також видаляємо непотрібні атрибути і оптимізуємо графіку.

Далі вказуємо, що файли лежать у папці src/img/svgIcons/, а створювати спрайт потрібно в папку dist/img/. Плагін автоматично генерує id для кожного зображення з його імені, тому іконкам потрібно давати осмислені назви. Далі використовуємо цей спрайт, тому що ми робили це раніше.

Використання міксинів для створення svg спрайтів

Щоразу вставляти спрайт через svg не дуже зручно. Якщо ви використовуєте якийсь html препроцесор, то це завдання можна спростити, створивши міксин для вставки спрайту. Розглянемо таку реалізацію з прикладу шаблонизатора nunjucks.

У nunjucks для таких завдань використовуються макроси. Спочатку створюємо окремий файл для всіх макросів _macro.html. У ньому створюємо макрос svgIcon для виведення зображень зі svg спрайту:

{% macro svgIcon(icon, class = '', path = '/assets/img/sprite.svg') %}
    <svg class="svg-icon {{ class }}">
      <use xlink:href="{{path}}#{{ icon }}"></use>
    </svg>
{% endmacro %}

Цей макрос приймає 3 параметри:

  • Id зображення;
  • Довільний клас зображення. За промовчанням значення порожнє. Для зручності кожній іконці ми додаємо клас svg-icon;
  • Шлях до файлу svg спрайту. За замовчуванням приймає значення, яке встановили в налаштування файлу gulp для генерації спрайту.
  • Далі необхідно імпортувати цей файл до основного документа:
{% import ./_macro.html" as macro %}

Тепер макрос готовий до використання. До всіх макросів можна звернутись через змінну macro. Розглянемо кілька прикладів виклику:

{{macro.svgIcon('instagram')}}
{{macro.svgIcon('instagram', ’social__icon’)}}
{{macro.svgIcon('instagram', ’social__icon’, ‘assets/img/socialSprite.svg’)}}

У першому прикладі ми просто виводимо іконку, у якої id дорівнює instagram. У другому варіанті додається клас social__icon. У третьому прикладі ми змінюємо шлях до спрайту.

Висновок

На цьому поки що все. Ми розглянули роботу з svg спрайтами. Це дуже зручний варіант роботи з графікою і має ряд переваг:

  • Використовує один http запит;
  • Є можливість змінювати стилі через CSS;
  • Не втрачається якість при масштабуванні;
  • Досить простий у реалізації.
Коментарі

Залишити відповідь

Натискаючи на кнопку, ви погоджуєтесь з умовами обробки персональних даних