Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scale SVG to container without mask/crop

Tags:

html

svg

I have tried many variants of the svg parameters, but have had no joy in scaling this particular SVG.

I am trying to contain this SVG into a container element that controls the size of the SVG.

I'm aiming for 500x309px.

What combination of width, height, viewBox and preserveAspectRatio can help me achieve this without having the SVG masked or cropped?

like image 395
sgb Avatar asked Mar 05 '12 12:03

sgb


People also ask

How do I scale SVG to fit a div?

Set the CSS attribute position:absolute on your <svg> element to cause it to sit inside and fill your div. (If necessary, also apply left:0; top:0; width:100%; height:100% .)

Can SVG images be scaled?

Once you add a viewBox to your <svg> (and editors like Inkscape and Illustrator will add it by default), you can use that SVG file as an image, or as inline SVG code, and it will scale perfectly to fit within whatever size you give it. However, it still won't scale quite like any other image.

What is viewBox in SVG?

The viewBox attribute defines the position and dimension, in user space, of an SVG viewport. The value of the viewBox attribute is a list of four numbers: min-x , min-y , width and height .


1 Answers

  1. You absolutely must have a viewBox attribute on your SVG element that describes the bounding box of the contents you want to be always visible. (The file that you link to does not; you'll want to add one.)

  2. To cause your SVG to fill an HTML element, put the CSS attribute position:relative (or position:absolute or position:fixed if appropriate) on your wrapper, and then

  3. Set the CSS attribute position:absolute on your <svg> element to cause it to sit inside and fill your div. (If necessary, also apply left:0; top:0; width:100%; height:100%.)

Once you have a viewBox and your SVG sized correctly the default value of the preserveAspectRatio attribute will do what you want. In particular, the default of xMidYMid meet means that:

  • The aspect ratio described by your viewBox will be preserved when rendering.
    By comparison, a value of none would allow non-uniform scaling.
  • The viewBox will always meet either top/bottom or left/right, with 'letterboxing' keeping the other dimension inside.
    By comparison, a value of slice ensures that your viewBox fully fills the rendering, with either the top/bottom or left/right falling outside the SVG.
  • The viewBox will be kept vertically and horizontally centered within the SVG viewport.
    By comparison, a value of xMinYMax would keep it in the bottom-left corner, with padding only to the right or top.

You can see this live here: http://jsfiddle.net/Jq3gy/2/

Try specifying explicit values for preserveAspectRatio on the <svg> element and press "Update" to see how they affect the rendering.

Edit: I've created a simplified version of the US Map with a viewBox (almost half the bytes) and used that in an updated demo to suit your exact needs: http://jsfiddle.net/Jq3gy/5/

like image 90
Phrogz Avatar answered Sep 29 '22 12:09

Phrogz