SVG sprite. Не отображается картинка

Собираю верстку в gulp 4, создаю спрайт из свг вот таким таском:

gulp.task('svgSpriteBuild', function () {
    return gulp.src('app/img/sprites/svg/*.svg')
    // minify svg
        .pipe(svgmin({
            js2svg: {
                pretty: true
            }
        }))
        // remove all fill, style and stroke declarations in out shapes
        .pipe(cheerio({
            run: function ($) {
                $('[fill]').attr('fill', 'inherit');
                $('[stroke]').removeAttr('stroke');
                $('[style]').removeAttr('style');
            },
            parserOptions: {xmlMode: true}
        }))
        // cheerio plugin create unnecessary string '>', so replace it.
        .pipe(replace('>', '>'))
        // build svg sprite
        .pipe(svgSprite({
            mode: {
                symbol: {
                    sprite: "../sprite.svg",
                }
            }
        }))
        .pipe(gulp.dest('app/img'));
});

Далее использую миксин в pug

mixin svg(name)
    svg&attributes(attributes)
        use(xlink:href=`app/img/sprite.svg#${name}`)

+svg('glasses')(class="glasses")

И выводится это все вот так введите сюда описание изображения

введите сюда описание изображения

Вот код свгэшки glasses

<svg width="21" height="9" viewBox="0 0 21 9" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M8.23804 5.22078C8.23804 4.3884 9.25137 3.71436 10.4999 3.71436C11.7485 3.71436 12.7618 4.3884 12.7618 5.22078" stroke="#253F41" stroke-width="1.5" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M4.61905 8.2381C6.61779 8.2381 8.2381 6.61779 8.2381 4.61905C8.2381 2.6203 6.61779 1 4.61905 1C2.6203 1 1 2.6203 1 4.61905C1 6.61779 2.6203 8.2381 4.61905 8.2381Z" stroke="#253F41" stroke-width="1.5" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M16.381 8.2381C18.3798 8.2381 20.0001 6.61779 20.0001 4.61905C20.0001 2.6203 18.3798 1 16.381 1C14.3823 1 12.762 2.6203 12.762 4.61905C12.762 6.61779 14.3823 8.2381 16.381 8.2381Z" stroke="#253F41" stroke-width="1.5" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

который после сборки в файле sprite.svg выглядит вот так:

<symbol fill="inherit" viewBox="0 0 21 9" id="glasses" xmlns="http://www.w3.org/2000/svg"><path d="M8.238 5.22c0-.832 1.013-1.506 2.262-1.506 1.248 0 2.262.674 2.262 1.507"/><path d="M4.619 8.238a3.62 3.62 0 100-7.238 3.62 3.62 0 000 7.238zm11.762 0a3.62 3.62 0 100-7.238 3.62 3.62 0 000 7.238z"/></symbol>

Не понимаю почему не видно картинки. Первое, что пришло в голову - неправильный путь до спрайта, но он находится вот тут app/img/sprite.svg, может в миксине неправильно оформила этот путь? Какие еще причины могут быть?


Ответы (1 шт):

Автор решения: Alexandr_TT

Основная ошибка в неправильном расположении тега <symbol>

Необходимо обёртывать <symbol> только код иконки, а не весь файл sprite.svg

Устройство спрайта

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

Symbol создает шаблон из любых svg-объектов, который в дальнейшем можно многократно использовать с помощью тэга use. Контент, расположенный внутри symbol, не отображается на странице.

Это цитата из статьи Символьный SVG-спрайт. Подробное руководство

Это отличная статья, написанная оч. доходчиво и с рабочими примерами. Также в конце статьи есть примеры настроек gulp

Ниже код вашего спрайта иконки и вызов её по id

<svg   viewBox="0 0 21 9"  xmlns="http://www.w3.org/2000/svg" style="display:none">
<symbol id="glasses"  fill="none" >
<path d="M8.23804 5.22078C8.23804 4.3884 9.25137 3.71436 10.4999 3.71436C11.7485 3.71436 12.7618 4.3884 12.7618 5.22078" stroke="#253F41" stroke-width="1.5" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M4.61905 8.2381C6.61779 8.2381 8.2381 6.61779 8.2381 4.61905C8.2381 2.6203 6.61779 1 4.61905 1C2.6203 1 1 2.6203 1 4.61905C1 6.61779 2.6203 8.2381 4.61905 8.2381Z" stroke="#253F41" stroke-width="1.5" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M16.381 8.2381C18.3798 8.2381 20.0001 6.61779 20.0001 4.61905C20.0001 2.6203 18.3798 1 16.381 1C14.3823 1 12.762 2.6203 12.762 4.61905C12.762 6.61779 14.3823 8.2381 16.381 8.2381Z" stroke="#253F41" stroke-width="1.5" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
 <symbol>
</svg> 

<svg> 
  <use xlink:href="#glasses" />
</svg>

Одну и ту же иконку с помощью <use> можно вызывать многократно.
Можно при этом стилизовать иконки, но чтобы решить проблему с shadow DOM, необходимо в CSS предусмотреть наследование (inherit)

 path {
 fill:inherit;
 stroke:inherit;
 }

 path {
 fill:inherit;
 stroke:inherit;
 }
 
<svg   viewBox="0 0 21 9"  xmlns="http://www.w3.org/2000/svg" style="display:none">
<symbol id="glasses"  fill="none" >
<path d="M8.23804 5.22078C8.23804 4.3884 9.25137 3.71436 10.4999 3.71436C11.7485 3.71436 12.7618 4.3884 12.7618 5.22078" stroke="#253F41" stroke-width="1.5" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M4.61905 8.2381C6.61779 8.2381 8.2381 6.61779 8.2381 4.61905C8.2381 2.6203 6.61779 1 4.61905 1C2.6203 1 1 2.6203 1 4.61905C1 6.61779 2.6203 8.2381 4.61905 8.2381Z" stroke="#253F41" stroke-width="1.5" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M16.381 8.2381C18.3798 8.2381 20.0001 6.61779 20.0001 4.61905C20.0001 2.6203 18.3798 1 16.381 1C14.3823 1 12.762 2.6203 12.762 4.61905C12.762 6.61779 14.3823 8.2381 16.381 8.2381Z" stroke="#253F41" stroke-width="1.5" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
 </symbol>
  
</svg> 

<svg>
 <use xlink:href="#glasses" stroke="red" /> 
   <use x="25" xlink:href="#glasses" stroke="green" /> 
     <use x="50" xlink:href="#glasses" stroke="dodgerblue" />
</svg>

→ Ссылка