foo.svg:但是,我想通过 CSS 向 SVG 添加其他样式,因此不能选择链接外部样式。如何制作......" /> foo.svg:但是,我想通过 CSS 向 SVG 添加其他样式,因此不能选择链接外部样式。如何制作......"> foo.svg:但是,我想通过 CSS 向 SVG 添加其他样式,因此不能选择链接外部样式。如何制作......" />
ChatGPT解决这个技术问题 Extra ChatGPT

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

I want to have an inline svg element's contents scale when size is non-native. Of course I could have it as a separate file and scale it like that.

index.html: <img src="foo.svg" style="width: 100%;" />

foo.svg: <svg width="123" height="456"></svg>

However, I want to add additional styles to the SVG thru CSS, so linking an external one is not an option. How do I make an inline SVG scale?

try precents in svg widths and heights.
@ncm How would it be done with JS?
To set it in JS: yoursvgelem.setAttribute("width", "100%"); and yoursvgelem.setAttribute("height", "100%"); @MawgsaysreinstateMonica

B
Brian Campbell

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:

https://ephemera.continuation.org/stackoverflow/svg-scale/1.svg

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>

https://ephemera.continuation.org/stackoverflow/svg-scale/2.svg

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>

https://ephemera.continuation.org/stackoverflow/svg-scale/3.svg

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>

https://ephemera.continuation.org/stackoverflow/svg-scale/4.svg

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>

https://ephemera.continuation.org/stackoverflow/svg-scale/5.svg

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>

https://ephemera.continuation.org/stackoverflow/svg-scale/6.svg

(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)


How do you make not only the viewBox preserveAspectRatio, but also the main box? I want width: 100%; height: auto for it.
@Dude: I think that the example with width="100%" and no height specified does what you want. I've added images to demonstrate. It has 100% width, and scales up the height proportionally. If that's not what you're looking for, can you try to clarify what you meant?
Oh. No problem actually. It's just a webkit bug. In Safari and Chrome the "real" height is 100% by default, not auto. How would I get around this then?
@Dude Ah, yes, I see. It works OK in Firefox, but no Chrome or Safari. According to the SVG Specification, Firefox appears to be correct; while the default value of width and height for an SVG element is 100%, this is not the CSS definition of 100% (100% of the containing block), but instead 100% of the viewport that has been specified based on the intrinsic aspect ratio (which is computed from the viewBox when that is given). I haven't yet found a solution for that problem that works in Chrome/Safari.
This works for me. I first create a viewBox attribute on the SVG element and set the value to "0 0 [original svg width] [original svg height]". Next I change the SVG element's width attribute to "auto" and height attribute to "100%". The container must also have a defined height. This scales the vector to 100% of the container height, allowing the width to float. Finally, set the SVG's CSS max-width to 100% to prevent overshooting the container.
a
agm1984

After like 48 hours of research, I ended up doing this to get proportional scaling:

NOTE: This sample is written with React. If you aren't using that, change the camel case stuff back to hyphens (ie: change backgroundColor to background-color and change the style Object back to a String).

<div
  style={{
    backgroundColor: 'lightpink',
    resize: 'horizontal',
    overflow: 'hidden',
    width: '1000px',
    height: 'auto',
  }}
>
  <svg
    width="100%"
    viewBox="113 128 972 600"
    preserveAspectRatio="xMidYMid meet"
  >
    <g> ... </g>
  </svg>
</div>

Here's what is happening in the above sample code:

VIEWBOX

MDN: https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/viewBox

min-x, min-y, width and height

ie: viewbox="0 0 1000 1000"

Viewbox is an important attribute because it basically tells the SVG what size to draw and where. If you used CSS to make the SVG 1000x1000 px but your viewbox was 2000x2000, you would see the top-left quarter of your SVG.

The first two numbers, min-x and min-y, determine if the SVG should be offset inside the viewbox.

My SVG needs to shift up/down or left/right

Examine this: viewbox="50 50 450 450"

The first two numbers will shift your SVG left 50px and up 50px, and the second two numbers are the viewbox size: 450x450 px. If your SVG is 500x500 but it has some extra padding on it, you can manipulate those numbers to move it around inside the "viewbox".

Your goal at this point is to change one of those numbers and see what happens.

You can also completely omit the viewbox, but then your milage will vary depending on every other setting you have at the time. In my experience, you will encounter issues with preserving aspect ratio because the viewbox helps define the aspect ratio.

PRESERVE ASPECT RATIO

MDN: https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/preserveAspectRatio

Based on my research, there are lots of different aspect ratio settings, but the default one is called xMidYMid meet. I put it on mine to explicitly remind myself. xMidYMid meet makes it scale proportionately based on the midpoint X and Y. This means it stays centered in the viewbox.

WIDTH

MDN: https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/width

Look at my example code above. Notice how I set only width, no height. I set it to 100% so it fills the container it is in. This is what is probably contributing the most to answering this Stack Overflow question.

You can change it to whatever pixel value you want, but I'd recommend using 100% like I did to blow it up to max size and then control it with CSS via the parent container. I recommend this because you will get "proper" control. You can use media queries and you can control the size without crazy JavaScript.

SCALING WITH CSS

Look at my example code above again. Notice how I have these properties:

resize: 'horizontal', // you can safely omit this
overflow: 'hidden',   // if you use resize, use this to fix weird scrollbar appearance
width: '1000px',
height: 'auto',

This is additional, but it shows you how to allow the user to resize the SVG while maintaining the proper aspect ratio. Because the SVG maintains its own aspect ratio, you only need to make width resizable on the parent container, and it will resize as desired.

We leave height alone and/or set it to auto, and we control the resizing with width. I picked width because it is often more meaningful due to responsive designs.

Here is an image of these settings being used:

https://i.stack.imgur.com/EU0SO.gif

If you read every solution in this question and are still confused or don't quite see what you need, check out this link here. I found it very helpful:

https://css-tricks.com/scale-svg/

It's a massive article, but it breaks down pretty much every possible way to manipulate an SVG, with or without CSS. I recommend reading it while casually drinking a coffee or your choice of select liquids.


This doesn't seem to work for any SVG -- If you don't have control of the SVG source, then this method fails when the SVG has a fixed width.
@user48956 You can always manipulate it after the fact with JavaScript.
Yes - you can always poke at the innards of various file formats with a programming - but you’d hope there’d be a method that works for all kinds of assets (e.g PNGs) and doesn’t require JavaScript programming.
what if you just have an SGV file, not an svg inline object?
@serge you add it to your html document as an <img> , <object> or <embed> tag with its src as the svg file. This way you lose the ability to modify it by CSS.. however you will remain able to modify its attributes with JavaScript. But if possible, better practice is to use svg inline.
K
KyleMit

You'll want to do a transform as such:

with JavaScript:

document.getElementById(yourtarget).setAttribute("transform", "scale(2.0)");

With CSS:

#yourtarget {
  transform:scale(2.0);
  -webkit-transform:scale(2.0);
}

Wrap your SVG Page in a Group tag as such and target it to manipulate the whole page:

<svg>
  <g id="yourtarget">
    your svg page
  </g>
</svg>

Note: Scale 1.0 is 100%


Ok. I don't want JS in this. Is there a way to have it transform to fit parent?
@bj setAttribute is the same thing as
What happens if a transform attribute already exists? It is overwritten?!
K
Kerry7777

Messing around & found this CSS seems to contain the SVG in Chrome browser up to the point where the container is larger than the image:

div.inserted-svg-logo svg { max-width:100%; }

Also seems to be working in FF + IE 11.


This solved the issue for me. I was only seeing the overflow in iOS though. Thanks!
Using both max-width: 100% and max-height: 100% will make the svg always scale to the container without ever overflowing or losing its aspect ratio.
@Gavin max-height: 100% not works for me, solved by using vh instead of %
Z
ZYinMD

Here's an easy way:

Type 1: Most SVGs have a viewbox, like so:

<svg viewBox="0 0 24 30" ...>

And you can easily control their size in css:

svg {
  height: 20px;
}

Type 2: If the svg has width and height, but doesn't have a viewport, like so:

<svg width="810" height="540">

Then you can just manually add a viewbox that's exactly the same as its width and hegith, like so:

<svg width="810" height="540" viewBox="0 0 810 540">

Then you can do the same as type 1.


k
keikai

Another simple way is

transform: scale(1.5);

where to add this in svg? this look css
@DimitriKopriwa in the transform attribute. E.g. <g transform="scale(1.5)">...</g> or you assign the element a class and use css.
c
canbax

changing the SVG file was not a fair solution for me so instead, I used relative CSS units.

vh, vw, % are very handy. I used a CSS like height: 2.4vh; to set a dynamic size to my SVG images.


F
Fabian Madurai

Adjusting the currentScale attribute works in IE ( I tested with IE 11), but not in Chrome.


J
Jan

If you want to scale SVG without preserveAspectRatio attribute.

This way SVG will always stretch to fill both width and height, and to do so, it will resize just width or height, if necessary, was looking for this for days, so thought to share it here in case someone else is looking for this

You have to remove width and height from <svg> and add viewBox attribute and add preserveAspectRatio="none"

example

<?xml version="1.0" encoding="utf-8"?>

<svg 
version="1.1" 
xmlns="http://www.w3.org/2000/svg" 
viewBox="0 0 5.8208332 15.9"
preserveAspectRatio="none">

<polygon points="480.4,200 0,200 0,0 480.4,0 599.9,100 " fill="#E1E1E1"/>
</svg>