123

I have some SVG files that specifies width and height as well as viewbox like this:

<svg width="576pt" height="432pt" viewBox="0 0 576 432" > ...

but how to display them in the browser at a size I decide? I want them smaller and have tried:

<object width="400" data="image.svg"></object>

but then I get visible scrollbars.

It works if I change the SVG files to set width and height to 100% instead, but I want to decide the size in the HTML regardless of what sizes are used in the SVG file. Is this possible ?

Volker E.
  • 5,911
  • 11
  • 47
  • 64
Zitrax
  • 19,036
  • 20
  • 88
  • 110
  • I'm confused, the last sentence reads like the solution you're searching for? Set SVG width/height to 100%/100% leaves it up to the HTML to define the area to draw it in? – mark Mar 13 '09 at 23:04
  • 3
    The problem is that I have found no way to change this in the library which I use to generate the svg files. And it would make sense to me if I could override this from html. So basically I wonder if there is another solution than to change the svg files. – Zitrax Mar 13 '09 at 23:25

9 Answers9

167

You can add "preserveAspectRatio" and "viewBox" attributes to the <svg> tag to accomplish this.

Open the .svg file in an editor and find the <svg> tag. in that tag, add the following attributes:

preserveAspectRatio="xMinYMin meet"
viewBox="0 0 {width} {height}"

Replace {width} and {height} with some defaults for the viewBox. I used the values from the "width" and "height" attributes of the SVG tag and it seemed to work.

Save the SVG and it should now scale as expected.

I found this information here:

https://blueprints.launchpad.net/inkscape/+spec/allow-browser-resizing

zwol
  • 135,547
  • 38
  • 252
  • 361
Jim Keller
  • 1,687
  • 2
  • 10
  • 3
  • 2
    #protip all you need to add it this preserveAspectRatio="xMinYMin meet" – samccone Oct 03 '12 at 19:41
  • 4
    @samccone: It seems that just `preserveAspectRatio="xMinYMin meet"` wasn't enough for me. I also needed to provide a `viewBox` as mentioned in the answer. Pity! – Frerich Raabe Mar 28 '13 at 19:51
  • 1
    You can also do `preserveAspectRatio="none"` if you want to stretch the svg out in arbitrary ways. – Matt Wonlaw Oct 07 '13 at 19:18
  • 6
    Don't fall for the same issue as i did: "viewbox" != "viewBox" :) – Dr.Ü Oct 14 '15 at 09:16
  • In addition, I had to set the actual width and height attributes to `100%` as [this answer](http://stackoverflow.com/a/12964856/603003) stated. – ComFreek Apr 09 '16 at 12:27
34

None of the answers given here worked for me when I asked this back in 2009. As I now had the same issue again I noticed that using the <img> tag and width together with an svg works fine.

<img width="400" src="image.svg" />
Stefan Mai
  • 23,367
  • 6
  • 55
  • 61
Zitrax
  • 19,036
  • 20
  • 88
  • 110
  • 6
    This is so much simpler than the other options! In case anyone's curious, here's a table of [which browsers can handle SVG's in tags](http://caniuse.com/svg-img). – dimo414 Jun 24 '12 at 00:38
  • 6
    This may be best path if there are no hyperlinks in SVG, otherwise, img is insufficient, and one still must use alternative like embed. – sdupton Jul 13 '12 at 16:50
  • 14
    When you use `` you lose all interactivity with links, javascript, etc. – gilly3 Oct 16 '12 at 07:33
  • 5
    Minor: The img element should be self closed, i.e. ``. – Jan Aagaard Oct 26 '12 at 20:43
  • 2
    Your img solution while it may look the same at a glance is completely different to actually drawing SVG in your browser. – mP. Oct 31 '12 at 02:12
  • @mP. What do you mean by completely different ? It's still rendered as SVG. An example of svg in can be seen here: http://tecfa.unige.ch/guides/svg/ex/html5/html5-with-img-src.html – Zitrax Oct 31 '12 at 07:24
  • Drop-shadows within the SVG are lost when displayed as an image tag. – Esger Apr 23 '13 at 10:08
  • 4
    @JanAagaard: It is [not required to close the img tag](http://stackoverflow.com/a/3558200/345716) except in XHTML. – Peter V. Mørch Sep 12 '13 at 07:13
  • @PeterV.Mørch: Correct. My point was that is not valid html, even though most browsers will probably allow it. – Jan Aagaard Sep 12 '13 at 09:04
  • This solution prevents the use of bitmapped images in the SVG. – Andy Swift Jul 29 '14 at 15:36
  • You cannot access the DOM of a SVG loaded in a `` tag. This might cause problems (see [How do you access the contents of an SVG file in an element?](http://stackoverflow.com/a/8134698/562769)). – Martin Thoma Mar 26 '15 at 10:16
  • Anyone using the `` tag may want to know about appending [SVG Fragement identifiers](https://www.w3.org/TR/SVG/linking.html#SVGFragmentIdentifiers), e.g. "``", which lets you control the aspect ratio, `viewBox`, etc the same as with inline SVG definitions. – brichins Jun 16 '16 at 17:05
  • Putting SVG as an image make inaccessible many of it's features (eg. links embedded in the svg don't work) so this is not the best idea (unless you don't care) – Kornel Aug 20 '16 at 11:23
  • This solution (2020) still prevents embedded javascript-animations in the SVG to run. Hence `` is not an option if you need embedded javascript- (or SMIL-) animations to run. – Igor Jun 14 '20 at 20:17
11
<body>

<div>
<object type="image/svg+xml" data="img/logo.svg">
   <img src="img/logo.svg" alt="Browser fail" />
</object>
</div>

img/logo.svg ...

<svg
   width="100%" 
   height="100%"
   viewBox="0 0 640 80"
   xmlns="http://www.w3.org/2000/svg"
   version="1.1" />

This setup worked for me.

Stephan
  • 41,764
  • 65
  • 238
  • 329
H Titan
  • 111
  • 1
  • 2
  • 1
    This actually works quite well! The really important thing is to actually define `viewBox="0 0 640 80"`. Apparently if this is not defined, you cannot really scale it or let CSS scale it for you by using e.g. `width: 100%` etc. – Igor Jun 14 '20 at 20:28
  • this works! tks, i needed to load svg into object to access contentDocument instead of 'img' tag – Dee Apr 13 '21 at 15:20
10

You can reach into the embedded svg using JavaScript:

var svg = document.getElementsByTagName('object')[0].\
  contentDocument.getElementsByTagName('svg')[0];
svg.removeAttribute('width');
svg.removeAttribute('height');

Since your svg already has a viewBox, Firefox should scale the 576 pixel width in the viewBox to the 400 pixel width in your document. Other svgs might benefit from a new viewBox derived from the advertised width and height (these are often the same numbers). Other browsers might benefit from different svg tweaks.

joeforker
  • 40,459
  • 37
  • 151
  • 246
9

I encountered a problem where iOS on an iPad would not correctly resize SVG images in a <object> tag.

The CSS style would increase or decrease size of the <object> container, but the image inside of it would not be modified (on iPad, iOS 7).

The SVG images were exported from Adobe Illustrator, and the solution turned out to be replacing the width and height in this:

<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="481.89px" height="294.843px" viewBox="0 0 481.89 294.843" 
enable-background="new 0 0 481.89 294.843"
xml:space="preserve">

with:

width="100%" height="100%"

I needed to use the <object> tag because the <img> tag does not currently support embedding bitmapped images in SVG's.

Andy Swift
  • 2,179
  • 3
  • 32
  • 53
5
  1. Set the missing viewbox and fill in the height and width values of the set height and height attributes in the svg tag

  2. Then scale the picture simply by setting the height and width to the desired percent values. Good luck.

  3. You can set a fixed aspect ratio with preserveAspectRatio="x200Y200 meet, but it's not necessary

e.g.

 <svg
   xmlns:dc="http://purl.org/dc/elements/1.1/"
   xmlns:cc="http://creativecommons.org/ns#"
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   xmlns:svg="http://www.w3.org/2000/svg"
   xmlns="http://www.w3.org/2000/svg"
   xmlns:xlink="http://www.w3.org/1999/xlink"
   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
   width="10%" 
   height="10%"
   preserveAspectRatio="x200Y200 meet"
   viewBox="0 0 350 350"
   id="svg2"
   version="1.1"
   inkscape:version="0.48.0 r9654"
   sodipodi:docname="namesvg.svg">
Lorenz Lo Sauer
  • 23,698
  • 16
  • 85
  • 87
4

Just use CSS to make the browser resize the SVG! Like so: <object style="width:30%"> See http://www.vlado-do.de/svg_test/ for more details. I just also tried it locally with an SVG that has its width and height given in "pt". It works well in Firefox.

Vlado
  • 161
  • 4
1

Here is a PHP solution using QueryPath based on Jim Keller's answer.

Once QueryPath is loaded just pass your svg script to the function.

function scaleableSVG($svg){
    $qp = qp($svg, 'svg');
    $width = $qp->attr('width');
    $height = $qp->attr('height');
    $qp->removeAttr('width')->removeAttr('height');                       
    $qp->attr('preserveAspectRatio', "xMinYMin meet");
    $qp->attr('viewBox', "0 0 $width $height");
    return $qp->html();
}
Dieter Gribnitz
  • 5,062
  • 2
  • 41
  • 38
1

Let see. I had to refresh my memory on SVG, I haven't used it much these years.

From what I found today, it seems that if you specify dimension of objects without units, they have a fixed size (in pixels, I think). Apparently, then, there is no way to resize them when you resize the SVG (it only change the viewport/canvas size).

Unless, as pointed out, you specify the size of the SVG in percentage OR specify a viewBox (eg. viewBox="0 0 600 500").

Now, if you have no way to change the exported SVG, you are out of luck, I fear. What library do you use?

PhiLho
  • 40,535
  • 6
  • 96
  • 134
  • The svg backend in matplotlib. I have tried functions like set_figwidth(val) but it does not seem to work, but I am not very familiar with this library so I might be looking at the wrong functions. – Zitrax Mar 14 '09 at 10:28