svg-sprite / svg-sprite

SVG sprites & stacks galore — A low-level Node.js module that takes a bunch of SVG files, optimizes them and bakes them into SVG sprites of several types along with suitable stylesheet resources (e.g. CSS, Sass, LESS, Stylus, etc.)
https://github.com/svg-sprite/svg-sprite
MIT License
1.94k stars 254 forks source link

How to scale the images inside the sprite? #191

Closed applecool closed 8 years ago

applecool commented 8 years ago

I have svg images of 32 x 32 and when I am using them in my application, I could explicitly mention background-size, width and height to scale the images.

Now, I am using the svg-sprite for all of my svg images. And I don't have the control on the scaling of the images. Let's say, I have 6 32 x 32 images in the sprite, then the sprite would be 32 x 192 px. When I use them in my code, they look smaller as previously I was scaling the 32 x 32 to 64 x 50 or 70 x 70. Now, I am unable to do it.

Is there a way to do it?

any help would be hugely appreciated. Thanks in advance.

Cheers :beers:

jkphl commented 8 years ago

@applecool The intended way of responsively using and scaling the SVG shapes in your website are

Please let me know if this helps!

applecool commented 8 years ago

@jkphl I tried it out but it didn't really work in my case. But I used a different hack to fix it. I used transform:scale(number) to scale the images inside the sprite which worked great. One could also use CSS zoom property too which is supported by all the browsers except for firefox.

jkphl commented 8 years ago

@applecool Ok, thanks. As this seems solved for you, I'll close this issue for now.

Chris2011 commented 7 years ago

Unfortunately I have the same problem and background-size: 100% auto; is not working, it shows me the whole sprite inside my div which has this style:

.icon {
   width: 16px;
   height: 16px;
   margin-right: .5em;
   background-size: 100% auto;
}

Most of the SVGs has 32x32 but I only want to show 16x16. When I do this without using background-size, it slices the svgs inside the div.

melloc01 commented 7 years ago

Any progress on this?

jkphl commented 7 years ago

@Chris2011 @melloc01 As I outlined above, there is nothing to make progress on here. Scaling the icons works perfectly fine as soon as the prerequisites are met. You just need an HTML element that's sized to the desired dimensions (i.e. must be a block or inline-block element) and a vertically (or horizontally; use auto 100% then) aligned sprite. We use it with background-size: 100% auto in production for years now, without any problems.

melloc01 commented 7 years ago

Hi @jkphl, what do you mean with vertically or horizontally aligned sprite? Do you mean having all icons on (let's say) X or Y axis?

I have created a fiddle that has a multi-dimensional svg, how would you use icon-big class with svg-close?

https://jsfiddle.net/tsua0755/2/

If the problem is the multi-dimensional thing, how would we crate a one-dimension svg? :thinking:

jkphl commented 7 years ago

@melloc01 Yes, for properly resizing a background sprite you'll need it to have "vertical" or "horizontal" layout. Just search the configuration docs for this and you'll find the appropriate option. I'm on my mobile phone only for the next couple of days so I won't be able to really help you any futher at the moment, sorry.

melloc01 commented 7 years ago

Cool! I'll try it out. It's on the docs!(duh) sorry for that. haha

Thanks @jkphl = )

Chris2011 commented 7 years ago

@jkphl for me it isn't working. This is the original view when I don't do anything, only set the

to width and height 16px: image

The SVGs are bigger 32x32 as I mentioned in an other comment. Thats why you only see a bit of the icon.

Now when I change the code to your suggestion, of course the div.icon is block and hast width and height 16px and background-size: 100% auto, than the result looks like:

image

I tried both 100% auto and auto 100%; Of course, this has nothing todo with your plugin, I only wanted to ask whether it is possible to have a functionality to scale the original SVGs to that size which I need. So it is 16x16.

Chris2011 commented 7 years ago

But the solution with background-size: 100% auto; doesn't help. I thought of other style which breaks it but no.

Chris2011 commented 7 years ago

Maybe it is related to your plugin, because it will add missing width and height and missing viewbox to the sprite so hard coded it is 32 in each line of the sprite. This needs to be flexible before, that I can say all my icons should be 16x16 instead of the original size. And while generating the icons should be changed and the sprite too.

iamtheluckyest commented 6 years ago

I was also having this issue where background-size: 100% auto; alone was not helping but rather displaying all of the images in my sprite at the same time. For me what solved the problem was using the align property. This was mentioned above but not explicitly enough for me to get it straight away so I thought I'd add my code in case it helps anyone in the future.

In my config I added the align property to shape and the layout property to mode.css :

{
    shape: {
        align: 'align-icons.yaml' 
    },
    mode: {
        css: {
            layout: 'horizontal',
            /* ... other properties .../*
        }
    }
}

Then I have the following in align-icons.yaml:

"*":
  "%s": .5

That along with background-size: auto 100%; gets it working for me.

diffen commented 6 years ago

@iamtheluckyest Can you please paste a diff of the final CSS output with/without the align property? This thread appears in google searches looking for a CSS solution, so it will help even those of us who maybe aren't using svg-sprite yet.

jkphl commented 6 years ago

I just became (re-)aware of this thread, being on holidays and with no proper development environment available at the moment.

@Chris2011 I know it's been a while, but what I can see in your screenshot is that you don't use a "vertical" or "horizontal" sprite layout (but a "packed" layout instead), which makes the sprite two-dimensional and thus basically unsuitable for CSS resizing.

@iamtheluckyest You seem to be using a "horizontal" sprite layout, which may work fine in your situation (depending on your concrete context), but my personal experience is that a "vertical" layout is more likely to fit the typical use cases (e.g. the one @Chris2011 shows).

Depending on the concrete situation, I'd use a "vertical" layout in combination with background-size: 100% auto, possibly limit the shape sizes to a particluar width, e.g. 16 or 32 px (shouldn't really matter as it's SVG and losslessly scaleable) and maybe also center the shapes as @iamtheluckyest suggested (depending on the shapes themselves, e.g. if the differ a lot in their aspect ratio). Hope this helps.

memoht commented 5 years ago

This may seem random, but this morning I was experimenting with basically doubling the size of a social sprite (horizontal) in my Ruby on Rails app. I saved the new SVG from Adobe Illustrator and when viewing in my browser the sprites shrunk. I tried the various hacks above and the auto 100% and nothing worked. I then took a closer look at the SVG file created from Illustrator in previous version and current, and noticed the newer export was missing something the older export had. Below is the difference in line one of the actual SVG files.

<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 350 60">

and to get my icons sizing properly again:

<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg"  width="350" height="60" viewBox="0 0 350 60">

The following is my CSS

.webicon {
  display: inline-block;
  background-image:url('<%= asset_path("sprite-social-r4.svg") %>');
  background-repeat: no-repeat;
  background-position: 0px 0px;
  white-space: nowrap;
  overflow: hidden;
  width: 65px;
  height: 60px;
  text-indent: -999em;
  text-align: left;
  margin-bottom: 5px;
  &.facebook { background-position: -0px 0; }
  &.twitter { background-position: -70px 0; }
  &.instagram { background-position: -140px 0; }
  &.linkedin { background-position: -210px 0; }
  &.website { background-position: -280px 0; }
}

and with that modification, these icons are now displaying as expected again.

Adding background-size: 100% auto; doesn't affect the result one way or the other. Always, just wanted to add to this thread because when I ran across this issue, I started searching the web for CSS SVG sprite not scaling and ran across this.

For reference, including a PNG copy of the actual sprite. sprite-social-r4

Chris2011 commented 5 years ago

@jkphl thx for the info it could be, but now I'm using another npm module called svg2png-many. This fits my needs. Thx anyway.

nroose commented 5 years ago

Adding background-size: 100% auto; doesn't affect the result one way or the other. Always, just wanted to add to this thread because when I ran across this issue, I started searching the web for CSS SVG sprite not scaling and ran across this.

Can you edit this to say background instead of backround?

jkphl commented 5 years ago

@nroose Done!