Autosize an Svg

Resizing SVG in html?

Open your .svg file with a text editor (it's just XML), and look for something like this at the top:

<svg ... width="50px" height="50px"...

Erase width and height attributes; the defaults are 100%, so it should stretch to whatever the container allows it.

How can I make an svg scale with its parent container?

To specify the coordinates within the SVG image independently of the scaled size of the image, use the viewBox attribute on the SVG element to define what the bounding box of the image is in the coordinate system of the image, and use the width and height attributes to define what the width or height are with respect to the containing page.

For instance, if you have the following:

<svg>
<polygon fill=red stroke-width=0
points="0,10 20,10 10,0" />
</svg>

It will render as a 10px by 20px triangle:

10x20 triangle

Now, if you set only the width and height, that will change the size of the SVG element, but not scale the triangle:

<svg width=100 height=50>
<polygon fill=red stroke-width=0
points="0,10 20,10 10,0" />
</svg>

10x20 triangle

If you set the view box, that causes it to transform the image such that the given box (in the coordinate system of the image) is scaled up to fit within the given width and height (in the coordinate system of the page). For instance, to scale up the triangle to be 100px by 50px:

<svg width=100 height=50 viewBox="0 0 20 10">
<polygon fill=red stroke-width=0
points="0,10 20,10 10,0" />
</svg>

100x50 triangle

If you want to scale it up to the width of the HTML viewport:

<svg width="100%" viewBox="0 0 20 10">
<polygon fill=red stroke-width=0
points="0,10 20,10 10,0" />
</svg>

300x150 triangle

Note that by default, the aspect ratio is preserved. So if you specify that the element should have a width of 100%, but a height of 50px, it will actually only scale up to the height of 50px (unless you have a very narrow window):

<svg width="100%" height="50px" viewBox="0 0 20 10">
<polygon fill=red stroke-width=0
points="0,10 20,10 10,0" />
</svg>

100x50 triangle

If you actually want it to stretch horizontally, disable aspect ratio preservation with preserveAspectRatio=none:

<svg width="100%" height="50px" viewBox="0 0 20 10" preserveAspectRatio="none">
<polygon fill=red stroke-width=0
points="0,10 20,10 10,0" />
</svg>

300x50 triangle

(note that while in my examples I use syntax that works for HTML embedding, to include the examples as an image in StackOverflow I am instead embedding within another SVG, so I need to use valid XML syntax)

Should I serve SVGs at the correct size or should I shrink them and let the browser resize them?

Like you said, SVGs are vectors.

should I go for a smaller file size

You cannot shrink the file size of an SVG. The SVG's XML code remains the same even if you lower the SVG's stated DPI or pixel size.

Will the SVG's file size change if the viewBox is changed?

It usually won't, or at least not much. Here's a convoluted example in which it WOULD change.

Here's the original ("small") version:

<svg viewBox="0 0 10 10" xmlns="http://www.w3.org/2000/svg">
<rect y="5" x="5" width="2" height="2"></rect>
<circle cx="5" cy="5" r="20%" fill="white"></circle>
</svg>

Now let's up the viewBox size. We need to proportionally increase the absolute coordinates of all elements.

<svg viewBox="0 0 10000000 10000000" xmlns="http://www.w3.org/2000/svg">
<rect y="5000000" x="5000000" width="2000000" height="2000000"></rect>
<circle cx="5000000" cy="5000000" r="20%" fill="white"></circle>
</svg>

The result is the same image, but 48 bytes larger (28%!). 48 bytes larger FOR NO GOOD REASON - the represented image is exactly the same, with the same level of precision.

This example is convoluted because most SVGs won't be like this - they will use floating point numbers, and even if the decimal (the literal .) position shifts, the number of digits will not - so there will be little or no size difference.

If you are changing the viewBox size and rescaling all of the values and do see a difference, then it is either like the convoluted example above, OR you are actually losing precision because the rescale is reducing the number of digits in the floating point values -- which would reduce the quality of the final image.

How to resize SVG with PHP?

Consider that "SVG" stands for "Scalable Vector Grafics".

  1. Imagick is a library for manipulating pixel-oriented grafics and as such unfit for vector grafic formats like SVG.

  2. SVGs are by their nature scalable. In most cases you will not need to rewrite them to change their size. If you display SVGs inside a webpage (via <img> or <object> tags, or as a CSS background-image, it will be displayed at the size defined for these elements, and if there is size information stored in the SVG file, that will be simply ignored. (Note that a lot of SVG files contain no display size information at all.)

  3. The only case you may need to set size information in the SVG file is if you display it as a standalone file (for example if you have a link pointing to the .svg itself).

    In this case, you can take advantage of the fact that SVG is a XML file:

    $dom = new DOMDocument('1.0', 'utf-8');
    $dom->load('/pathe/to/my/svg.svg');
    $svg = $dom->documentElement;

    if ( ! $svg->hasAttribute('viewBox') ) { // viewBox is needed to establish
    // userspace coordinates
    $pattern = '/^(\d*\.\d+|\d+)(px)?$/'; // positive number, px unit optional

    $interpretable = preg_match( $pattern, $svg->getAttribute('width'), $width ) &&
    preg_match( $pattern, $svg->getAttribute('height'), $height );

    if ( $interpretable ) {
    $view_box = implode(' ', [0, 0, $width[0], $height[0]]);
    $svg->setAttribute('viewBox', $view_box);
    } else { // this gets sticky
    throw new Exception("viewBox is dependent on environment");
    }
    }

    $svg->setAttribute('width', '1000');
    $svg->setAttribute('height', '1000');
    $dom->save('/pathe/to/my/new.svg');

    There are some tricky cases if the element has no viewBox attribute and the width and height have non-px units. Handling them requires a deeper understanding of SVG. It would be best to assure that the SVG files produced by the "other script" always have a viewBox. Then the conditional section can be left out.

    The term "resolution" is inapplicable for vector grafics. Width and height can be dimensionless numbers (representing pixel for the purpose of rendering into an output device, for example the screen), or any valid CSS length unit: em, ex, px, pt, pc, cm, mm, in, and percentages.

Resize SVG by changes in path

No you can't. You'd have to change the SVG path to fit the box, but you can't "resize" per-se.

I manually resized your path to fit the box.

<path fill="#3E3E3E" d="M1.2 3.3H4a1 1 0 1 1 0 1.8H.6a1 1 0 0 1-.9-.9V0a1 1 0 0 1 1.9 0v1.4A11 11 0 0 1 20 8.6c0 .5-.4.9-1 .9a1 1 0 0 1-.9-1A9.2 9.2 0 0 0 12.3 1a9.2 9.2 0 0 0-10 2.3ZM17.4 16.1A11 11 0 0 1-1 8.9c0-.5.4-.9 1-.9.4 0 .8.4.9 1a9.2 9.2 0 0 0 5.8 7.5 9.2 9.2 0 0 0 10-2.3h-2.6a1 1 0 1 1 0-1.8h4.3a1 1 0 0 1 .9.9v4.2a1 1 0 0 1-1.9 0v-1.4Z"></path>

How I did it:

I used svgomg with precision: 1, to simplify the path to a point where it was small enough for me to actually manually edit.

Then I split it into two separate paths (top and bottom arrows) (using
the Z as the path separator), wrapped them in <g transform="translate(x, y)"></g> until it looked right, copied the
remainder back into svgomg where it is smart enough to convert the
transforms into a single path.



Related Topics



Leave a reply



Submit