如何使<svg>元素扩展或收缩到其父容器?


112

目标是使<svg>元素扩展到其父容器的大小,在这种情况下为a <div>,无论该容器有多大或多小。

代码:

<style>
    svg, #container{
        height: 100%;
        width: 100%;
    }
</style>

<div id="container">
    <svg xmlns="http://www.w3.org/2000/svg" version="1.1" >
         <rect x="0" y="0" width="100" height="100" />
    </svg>
</div>

解决此问题的最常见方法似乎是viewBox<svg>元素上设置属性。

viewBox="0 0 widthOfContainer heightOfContainer"

但是,这在元素内的<svg>元素具有预定义的宽度和/或高度的情况下似乎不起作用。例如,<rect>在上面的代码中,元素的宽度和高度已明确设置。

因此,显而易见的解决方案是在这些元素上也使用百分比宽度和百分比高度。但这是否必须要做?特别是,由于<img src=test.svg >可以很好地工作并且可以在没有明显设置<rect>高度和宽度的情况下进行扩展/收缩。

如果像这样的元素<rect>和其他类似的元素必须以百分比定义其宽度和高度,则Inkscape中可以通过一种方式对其进行设置,以使<svg>文档中的所有元素都使用百分比的宽度,高度等。 ?


1
将svg保存为文件,而不是将其引用为图像,例如<img src =“ file.svg” />,这样您就可以使用width:100%或height:100%
Burimi

Answers:


56

viewBox不是容器的高度,这是你的绘图的大小。将viewBox宽度定义为100个单位,然后将宽度定义rect为10个单位。此后,无论您缩放SVG的大小如何,rect都将是图像宽度的10%。


33
但是问题是:如何缩放SVG?
Adrian Heine 2012年

6
@AdrianLang当您在SVG对象上设置尺寸时,缩放会自动发生,就像问题代码中已经完成的那样。 这是示例的固定版本
robertc

您说得对,太好了,这实际上对我有用。我想我的问题是我的svg根元素中的高度和宽度属性。
Adrian Heine 2012年

2
对该小提琴做了一些细微的调整,以在不保留宽高比的情况下水平和垂直地强制调整大小,并使其在IE中起作用,而提交的小提琴@robertc却没有。希望它能对以后的人有所帮助!
先生Crimson

3
默认情况下,您的svg会尽可能缩放,以使其完全可见,但保留其宽高比(因此,正方形viewBox不会完全填充矩形父级)。如果您确实要强制其完全覆盖父容器,请向SVG元素添加preserveAspectRatio =“ none”
patricksurry 2015年

24

假设我有一个看起来像这样的SVG: 图片1

我想将其放在div中,并使其以响应方式填充div。我的操作方式如下:

首先,我在诸如inkscape之类的应用程序中打开SVG文件。在“文件”->“文档属性”中,我将文档的宽度设置为800px,将高度设置为600px(您可以选择其他大小)。然后,我将SVG放入此文档中。

图片2

然后,我将此文件另存为新的SVG文件,并从该文件获取路径数据。现在,在HTML中执行魔术的代码如下:

<div id="containerId">    
    <svg
    id="svgId" 
    xmlns:svg="http://www.w3.org/2000/svg"
    xmlns="http://www.w3.org/2000/svg"
    version="1.1"
    x="0"
    y="0"
    width="100%"
    height="100%"
    viewBox="0 0 800 600"
    preserveAspectRatio="none">
       <path d="m0 0v600h800v-600h-75.07031l-431 597.9707-292.445315-223.99609 269.548825-373.97461h-271.0332z" fill="#f00"/>
    </svg>
</div>

请注意,SVG的宽度和高度都设置为100%,因为我们希望它垂直和水平填充容器,但是viewBox的宽度和高度与inkscape中文档的宽度和高度相同,为800px X 600像素。接下来需要做的是将preserveAspectRatio设置为“ none”。如果您需要有关此属性的更多信息,这里是一个很好的链接。这就是全部。

还有一件事是,该代码可在几乎所有主流浏览器(甚至是旧浏览器)上运行,但是在某些版本的android和ios上,您需要使用一些javascrip / jQuery代码来保持一致。我在文档准备和调整大小功能中使用以下内容:

$('#svgId').css({
    'width': $('#containerId').width() + 'px',
    'height': $('#containerId').height() + 'px'
});

希望能帮助到你!


5
+1表示reserveAspectRatio注释。在高低搜寻以使SVG实际拉伸(而不是缩放)到div之后,这是正确的答案。
adelphus 2015年

@Gazoris,感谢您的精彩回答。有同样的问题。如果我的svg嵌套,该怎么办。例如,<svg> <svg id =“ 1”> </ svg> <svg id =“ 2”> </ svg> </ svg>我想有条件地显示svg 1和2,并且它应该使用宽度和高度的容器。<div id =“ container” style =“ width:200px; height:200px;”> </ div>请您帮我一下。
Prasad Parab

@Reza Baradaran:天才。
DanMad

6

最近为我工作的是从标记和所有子标记中删除全部height=""width=""属性<svg>。然后,您可以使用父容器的高度或宽度的百分比进行缩放。


5
你能举一个有效的例子吗?我什么也做不了。
迈克尔(Michael

2

@robertc是正确的,但您还需要注意,这svg, #container会导致svg呈指数缩放,但除100%之外的任何值(一次为#container,一次为svg)。

换句话说,如果我对两个元素都应用50%的h / w,则实际上是50%的50%,即0.5 * .5,等于.25或25%比例。

如@robertc建议的那样,使用一个选择器即可正常工作。

svg {
  width:50%;
  height:50%;
}

这是因为你的选择svg, #container符合双方svgDOM元素#containerDOM元素。我相信您是在寻找svg #container,但是如果您仍在使用ID,则无需指定父对象。
Nit 2014年

那不是我所说的,“一次用于#container,一次用于svg”吗?
贾斯汀·普尼

1
噢,对不起,您是对的,但您的回答措词有点奇怪,导致误解。听起来好像刚开始是在谈论潜在的陷阱。
2014年

1

对于您的iphone,您可以在头上使用:

"width=device-width"
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.