Можно ли менять размер SVG если он находится в спрайте?

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

Для генирации спрайтов использую gulp-svg-sprite с базовыми настройками, на выходе получаю такой код SCG спрайта:

<?xml version="1.0" encoding="utf-8"?><svg width="100" height="50" viewBox="0 0 100 50" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><view id="ico-menu" viewBox="0 0 50 50"/><svg viewBox="0 0 50 50" enable-background="new 0 0 50 50" fill="#F5F5F5" width="50" height="50"><path d="M10 12h30v4H10zM10 22h30v4H10zM10 32h30v4H10z"/></svg><view id="ico-menu-hover" viewBox="50 0 50 50"/><svg viewBox="0 0 50 50" enable-background="new 0 0 50 50" fill="#B6B6B6" width="50" height="50" x="50"><path d="M10 12h30v4H10zM10 22h30v4H10zM10 32h30v4H10z"/></svg></svg>


%svg-common {
	background-repeat: no-repeat;
	background-image: url(svg/sprite.view.svg);
}

.svg-ico-menu {
	background-position: 0 0;
	@extend %svg-common;
}

.svg-ico-menu-dims {
	width: 50px;
	height: 50px;
}

.svg-ico-menu-hover {
	background-position: 100% 0;
	@extend %svg-common;
}

.svg-ico-menu-hover-dims {
	width: 50px;
	height: 50px;
}


При попытке изменить width или height размер не хочет меняться, только обрезается, либо залазиет сосед.

Буду благодарен если кто-то поможет разобраться и вообще настроить удобно работу с SVG спрайтами. С меня пиво :)
  • Вопрос задан
  • 8396 просмотров
Решения вопроса 1
gatilin222
@gatilin222
Frontend-разработчик
О том, как сделать спрайт и оптимизировать его загрузку я написал в статье Как мы используем SVG-спрайты
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 3
@faragly
В svg спрайте изменять размер определенного куска не получится, если не менять background-size для спрайта и width и height для отдельного взятого svg. Есть прекрасная статья, материалы которой я использовал у себя. На этой неделе решил собирать svg-спрайты папками (раньше папками собирались только png), иконок было много, дизайнер нарисовал размеры больше чем нужно, менять размер каждой иконки слишком рутинно. Реализовал миксины (mixin svg-sprite это mixin sprite из вышеуказанной статьи):
// svg из папки генерируют scss файлы {название_папки}.scss
@import '../sprites/svg.scss',
        '../sprites/ne-svg.scss';

// список спрайтов помещаем в массив
$svg-sprites: (svg: $svg-icons, ne-svg: $ne-svg-icons);

$svg-sprite: map-get($svg-icons, sprite) !default;
$ne-svg-sprite: map-get($ne-svg-icons, sprite) !default;

// Gets an attribute from the sass map
@function sprite-attr($icon, $attr, $sprite) {
    $newIcon: map-get($sprite, $icon);
    @if $newIcon == null {
        @warn "Can't find an icon with the name #{$icon}";
    }
    @return map-get($newIcon, $attr);
}

@function icon-attr($icon, $sprite) {
    $sprite: map-get($svg-sprites, $sprite);
    $attr: (
        width: sprite-attr($icon, width, $sprite),
        height: sprite-attr($icon, height, $sprite),
        x: sprite-attr($icon, backgroundX, $sprite),
        y: sprite-attr($icon, backgroundY, $sprite)
    );

    @return $attr;
}

%svg-sprite {
    display: inline-block;
    background-image: url(map-get($svg-sprite, svgPath));
    background-size: map-get($svg-sprite, width) map-get($svg-sprite, height);
}

%ne-svg-sprite {
    display: inline-block;
    background-image: url(map-get($ne-svg-sprite, svgPath));
    background-size: map-get($ne-svg-sprite, width) map-get($ne-svg-sprite, height);
}

@mixin ne-svg-bg-size($percent: 100) {
    $bg-size-x: map-get($ne-svg-sprite, width);
    $bg-size-y: map-get($ne-svg-sprite, height);
    background-size: round($bg-size-x * $percent / 100) round($bg-size-y * $percent / 100);
}

@mixin svg-sprite($icon, $type: all, $sprite: svg) {
    @if $type == all {
        // Shares the backgrounds
        @extend %#{$sprite}-sprite;
    }

    $iconMap: icon-attr($icon, $sprite);

    // Outputs dimensions in em
    @if $type == all or $type == size {
        width: map-get($iconMap, width);
        height: map-get($iconMap, height);
    }

    // Outputs background position in px
    @if $type == all or $type == bg {
        background-position: map-get($iconMap, x) map-get($iconMap, y);
    }
}

@mixin svg-sprite-percent($icon, $type: all, $sprite: svg, $percent: 100) {
    @if $percent == 100 {
        @include svg-sprite-percent($icon, $type, $sprite);
    } @else {
        @if $type == all {
            // Shares the backgrounds
            @extend %#{$sprite}-sprite;
            @include ne-svg-bg-size($percent);
        }

        $iconMap: icon-attr($icon, $sprite);

        @if $type == all or $type == size {
            width: round(map-get($iconMap, width) * $percent / 100);
            height: round(map-get($iconMap, height) * $percent / 100);
        }

        @if $type == all or $type == bg {
            background-position: round(map-get($iconMap, x) * $percent / 100) round(map-get($iconMap, y) * $percent / 100);
        }
    }
}

Использую такой шаблон для генерации файла scss, (параметр common: folderName указывается в сборке gulp-svg-sprite)
// {{date}}

${{common}}-icons: (
    sprite: (width: {{spriteWidth}}px, height: {{spriteHeight}}px, pngPath: '/source/i/{{common}}-sprite.png', svgPath: '/source/i/{{common}}-sprite.svg'),
{{#shapes}}
    {{base}}: (width: {{width.inner}}px, height: {{height.inner}}px, backgroundX: {{position.absolute.x}}px, backgroundY: {{position.absolute.y}}px),
{{/shapes}});


А использую это примерно так (в папке ne-svg находятся файлы file-gray.svg, help-gray.svg, hand-icon.svg):
$icons: (file: file-gray, help: help-gray, touch: hand-icon);
@each $i, $icon in $icons {
    .icon--#{$i} {
        @extend %ne-svg-sprite;
        @include svg-sprite-percent($icon, all, ne-svg, 66);
    }
}


Возможно написал избыточную информацию, но мне кажется мой опыт будет полезным еще кому-то, хотя не претендую на звание изящного решения. По любым вопросам готов помочь.
Ответ написан
Комментировать
jlekapb
@jlekapb
.do
Попробуйте background-size

Статья Масштабируем CSS спрайты с SVG, убивая сразу трех зайцев: habrahabr.ru/post/141654
Ответ написан
@alltiptop
viewBox убрать в заголовке svg
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы