K
K
kamwork2015-02-05 20:41:27
css
kamwork, 2015-02-05 20:41:27

Is it possible to resize an SVG if it is in a sprite?

Hello. I've been struggling for days to make it possible to work with SVG as comfortably as with PNG, namely, I throw files with SVG into my daddy, GULP builds a sprite from them, creates the necessary sass file with impurities that can be used.
To generate sprites, I use gulp-svg-sprite with basic settings, at the output I get the following SCG sprite code:

<?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;
}

When you try to change the width or height, the size does not want to change, it is only cut off, or the neighbor climbs.
I would be grateful if someone could help me figure it out and generally set up a convenient way to work with SVG sprites. Beer from me :)

Answer the question

In order to leave comments, you need to log in

4 answer(s)
M
Maxim Gatilin, 2016-03-17
@kamwork

I wrote about how to make a sprite and optimize its loading in the article How we use SVG sprites

F
faragly, 2016-06-12
@faragly

In an svg sprite, changing the size of a certain piece will not work unless you change the background-size for the sprite and the width and height for a single svg. There is an excellent article , the materials of which I used at home. This week I decided to collect svg sprites in folders (before only png folders were collected), there were a lot of icons, the designer drew the sizes larger than necessary, changing the size of each icon is too routine. Implemented mixins (mixin svg-sprite is the mixin sprite from the above article):

// 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);
        }
    }
}

I use this template to generate a scss file, (the common: folderName parameter is specified in the gulp-svg-sprite assembly)
// {{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}});

And I use it like this (in the ne-svg folder there are files 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);
    }
}

Perhaps I wrote redundant information, but it seems to me that my experience will be useful to someone else, although I do not pretend to be an elegant solution. Ready to help for any questions.

J
jlekapb, 2015-02-05
@jlekapb

Try background-size
the article Scaling CSS sprites with SVG, killing three birds with one stone: habrahabr.ru/post/141654

A
alltiptop, 2016-01-14
@alltiptop

viewBox remove in svg header

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question