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

Posted

技术标签:

【中文标题】如何使 <svg> 元素扩展或收缩到其父容器?【英文标题】:How to make a <svg> element expand or contract to its parent container? 【发布时间】:2012-02-13 16:48:15 【问题描述】:

目标是让&lt;svg&gt; 元素扩展到其父容器的大小,在本例中为&lt;div&gt;,无论该容器有多大或多小。

代码:

<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"   />
    </svg>
</div>

这个问题最常见的解决方案似乎是在&lt;svg&gt; 元素上设置viewBox 属性。

viewBox="0 0 widthOfContainer heightOfContainer"

但是,如果&lt;svg&gt; 元素中的元素具有预定义的宽度和/或高度,这似乎不起作用。例如,&lt;rect&gt; 元素,在上面的代码中,明确设置了它的宽度和高度。

因此,显而易见的解决方案是在这些元素上也使用 % 宽度和 % 高度。但这甚至必须做吗?特别是,由于 &lt;img src=test.svg &gt; 工作正常并且扩展/收缩没有任何问题,明确设置 &lt;rect&gt; 高度和宽度。

如果像 &lt;rect&gt; 这样的元素和其他类似的元素必须以百分比定义它们的宽度和高度,Inkscape 有没有办法设置它,以便所有具有 &lt;svg&gt; 文档的元素都使用百分比宽度,高度等。而不是固定尺寸?

【问题讨论】:

将 svg 保存为文件,而不是将其作为图像引用,例如 这样您就可以使用 width:100% 或 height:100% How can I make an svg scale with its parent container?的可能重复 【参考方案1】:

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

【讨论】:

但问题是:如何缩放 SVG? @AdrianLang 当您在 SVG 对象上设置大小时,缩放会自动发生,正如问题代码中已经完成的那样。 Here's a fixed version of the example. 你说得对,太棒了,这实际上对我有用。我想我的问题是我的 svg 根元素中的高度和宽度属性。 I made some minor tweaks 到那个小提琴,以在不保留纵横比的情况下水平和垂直强制调整大小,并使其在 IE 中工作,而提交的小提琴 @robertc 不是。希望它能帮助别人! 默认情况下,您的 svg 将尽可能大地缩放,使其完全可见,但保留其纵横比(因此方形 viewBox 不会完全填充矩形父级)。如果你真的想强制它完全覆盖父容器,添加preserveAspectRatio="none"到SVG元素。【参考方案2】:

假设我有一个如下所示的 SVG:

我想把它放在一个 div 中,让它响应式地填充 div。我的做法如下:

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

然后我将这个文件保存为一个新的 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"
    
    
    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 中文档的宽高相同是 800 像素 X 600 像素。您需要做的下一件事是将preserveAspectRatio 设置为“none”。如果您需要了解有关此属性的更多信息,这里有一个很好的link。仅此而已。

还有一点是,这段代码几乎适用于所有主流浏览器,甚至是旧浏览器,但在某些版本的 androidios 上,您需要使用一些 javascrip/jQuery 代码来保持一致。我在文档准备和调整大小功能中使用以下内容:

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

希望对你有帮助!

【讨论】:

+1 表示 preserveAspectRatio 注释。在高低搜寻以使 SVG 实际拉伸(而不是缩放)到 div 之后,这是正确的答案。 @Gazoris,感谢您的精彩回答。有同样的问题。如果我的 svg 是嵌套的怎么办。例如, 我想有条件地显示 svg 1 和 2,它应该采用宽度和高度的容器。 你能帮我解决这个问题吗? @Reza Baradaran:天才。【参考方案3】:

最近对我有用的是从&lt;svg&gt; 标记和所有子标记中删除所有height=""width="" 属性。然后,您可以使用父容器的高度或宽度的百分比进行缩放。

之前:

<svg   viewBox="0 0 3212 3212" fill="none" xmlns="http://www.w3.org/2000/svg">
   circle cx="1606" cy="1606" r="1387" stroke="black" stroke-/>
</svg>

之后:

<svg viewBox="0 0 3212 3212" fill="none" xmlns="http://www.w3.org/2000/svg">
   circle cx="1606" cy="1606" r="1387" stroke="black" stroke-/>
</svg>

【讨论】:

你能举个例子吗?我不能让它做任何事情。 这对我也有用。我已编辑此问题以添加示例。【参考方案4】:

@robertc 说得对,但您还需要注意,svg, #container 会导致 svg 以指数方式缩放,而不是 100%(一次用于#container,一次用于svg)。

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

按照@robertc 的建议使用时,一个选择器可以正常工作。

svg 
  width:50%;
  height:50%;

【讨论】:

那是因为你的选择器svg, #container 匹配both svg dom 元素 #container dom 元素。我相信您是在寻找 svg #container,但如果您仍然使用 ID,则不需要指定父级。 这不正是我所说的,“一次用于#container,一次用于svg”吗? 哦,对不起,你是对的,但你的回答有点奇怪,导致了误解。听起来你一开始就在谈论一个潜在的问题。【参考方案5】:

对于您的 iPhone,您可以在您的头部应答器中使用:

"width=device-width"

【讨论】:

以上是关于如何使 <svg> 元素扩展或收缩到其父容器?的主要内容,如果未能解决你的问题,请参考以下文章

SVG 的绝对定位导致内部路径元素移动到其包含元素之外

如何使svg颜色不同[重复]

使 SVG 文本不可选

如何使用 JavaScript 在 <object> 标记内选择 SVG 元素?

如何使用not选择器定位ID中的元素?

如何使 div 不大于其内容?