【问题标题】:How can I make an svg scale with its parent container?如何使用其父容器制作 svg 比例尺?
【发布时间】:2013-10-29 08:46:54
【问题描述】:

当 size 不是原生时,我希望有一个内联 svg 元素的内容缩放。当然,我可以将它作为一个单独的文件并像这样缩放它。

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

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

但是,我想通过 CSS 向 SVG 添加其他样式,因此不能选择链接外部样式。如何制作内联 SVG 比例?

【问题讨论】:

  • 尝试 svg 宽度和高度的 precents。
  • @ncm 用JS怎么做?

标签: css html svg scaling


【解决方案1】:

要指定 SVG 图像内的坐标而与图像的缩放大小无关,请使用 SVG 元素上的viewBox 属性来定义图像的边界框在图像坐标系中的位置,并使用widthheight 属性来定义相对于包含页面的宽度或高度。

例如,如果您有以下情况:

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

它将呈现为 10 x 20 像素的三角形:

现在,如果您只设置宽度和高度,这将改变 SVG 元素的大小,但不会缩放三角形:

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

如果您设置视图框,这会导致它转换图像,以使给定的框(在图像的坐标系中)按比例放大以适应给定的宽度和高度(在页面的坐标系中)。例如,将三角形放大为 100 像素 x 50 像素:

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

如果你想把它放大到 HTML 视口的宽度:

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

请注意,默认情况下会保留纵横比。因此,如果您指定元素的宽度应为 100%,但高度为 50px,它实际上只会放大到 50px 的高度(除非您的窗口非常窄):

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

如果您确实希望它水平拉伸,请使用 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>

(请注意,虽然在我的示例中我使用了适用于 HTML 嵌入的语法,但为了将示例作为图像包含在 StackOverflow 中,我改为嵌入到另一个 SVG 中,因此我需要使用有效的 XML 语法)

【讨论】:

  • 如何制作不仅 viewBox preserveAspectRatio,还制作主框?我想要宽度:100%;高度:自动为它。
  • @Dude:我认为带有width="100%" 且未指定高度的示例可以满足您的需求。我添加了图像来演示。它有 100% 的宽度,并按比例放大高度。如果这不是您要查找的内容,您能否尝试澄清您的意思?
  • 哦。其实没问题。这只是一个 webkit 错误。在 Safari 和 Chrome 中,“真实”高度默认为 100%,而不是自动。那我该如何解决呢?
  • @Dude 啊,是的,我明白了。它在 Firefox 中运行良好,但在 Chrome 或 Safari 中没有。根据SVG Specification,Firefox 似乎是正确的;虽然 SVG 元素的 widthheight 的默认值是 100%,但这不是 100%(包含块的 100%)的 CSS 定义,而是基于指定的视口的 100%关于内在纵横比(在给定时从viewBox 计算)。我还没有找到适用于 Chrome/Safari 的该问题的解决方案。
  • 这对我有用。我首先在 SVG 元素上创建一个 viewBox 属性并将值设置为“0 0 [原始 svg 宽度] [原始 svg 高度]”。接下来,我将 SVG 元素的 width 属性更改为“auto”,将 height 属性更改为“100%”。容器还必须具有定义的高度。这会将向量缩放到容器高度的 100%,允许宽度浮动。最后,将 SVG 的 CSS 最大宽度设置为 100% 以防止超出容器。
【解决方案2】:

经过大约 48 小时的研究,我最终这样做是为了获得比例缩放:

注意:这个示例是用 React 编写的。如果您不使用它,请将驼峰式的东西改回连字符(即:将backgroundColor 更改为background-color 并将样式Object 更改回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>

以下是上述示例代码中发生的情况:

视图框

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

min-x, min-y, 宽度和高度

即:viewbox="0 0 1000 1000"

Viewbox 是一个重要的属性,因为它基本上告诉 SVG 要绘制什么尺寸以及在哪里绘制。如果您使用 CSS 将 SVG 设为 1000x1000 像素,但您的视图框为 2000x2000,您会看到左上角的四分之一 SVG。

前两个数字 min-x 和 min-y 确定 SVG 是否应在视图框内偏移。

我的 SVG 需要上/下或左/右移动

检查一下:viewbox="50 50 450 450"

前两个数字会将您的 SVG 向左移动 50 像素并向上移动 50 像素,后两个数字是视图框大小:450x450 像素。如果您的 SVG 是 500x500 但上面有一些额外的填充,您可以操纵这些数字在“视图框”内移动它。

此时您的目标是更改其中一个数字,看看会发生什么。

您也可以完全省略视图框,但是您的里程数会根据您当时的所有其他设置而有所不同。根据我的经验,您会遇到保留纵横比的问题,因为视图框有助于定义纵横比。

保留纵横比

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

根据我的研究,有很多不同的纵横比设置,但默认设置为xMidYMid meet。我把它放在我的身上是为了明确地提醒自己。 xMidYMid meet 使它根据中点 X 和 Y 按比例缩放。这意味着它在视图框中保持居中。

宽度

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

看看我上面的示例代码。请注意我如何只设置宽度,不设置高度。我将它设置为 100%,这样它就会填满它所在的容器。这可能是回答这个 Stack Overflow 问题的最大贡献。

您可以将其更改为您想要的任何像素值,但我建议像我所做的那样使用 100% 将其放大到最大尺寸,然后通过父容器使用 CSS 对其进行控制。我推荐这个,因为你会得到“适当的”控制。您可以使用媒体查询,并且无需疯狂的 JavaScript 即可控制大小。

使用 CSS 进行缩放

再次查看我上面的示例代码。注意我是如何拥有这些属性的:

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

这是附加的,但它向您展示了如何允许用户调整 SVG 的大小,同时保持适当的纵横比。由于 SVG 保持自己的纵横比,您只需在父容器上调整宽度,它会根据需要调整大小。

我们不理会高度和/或将其设置为自动,并通过宽度控制调整大小。我选择宽度是因为响应式设计通常更有意义。

这是正在使用的这些设置的图像:

如果您阅读了此问题中的所有解决方案,但仍然感到困惑或不太明白您需要什么,请在此处查看此链接。我发现它很有帮助:

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

这是一篇庞大的文章,但它几乎分解了所有可能的 SVG 操作方式,无论是否使用 CSS。我建议在随便喝杯咖啡或选择您选择的液体时阅读它。

【讨论】:

  • 这似乎不适用于任何 SVG -- 如果您无法控制 SVG 源,那么当 SVG 具有固定宽度时,此方法将失败。
  • @user48956 你总是可以在事后使用 JavaScript 来操作它。
  • 是的——你总是可以通过编程来探究各种文件格式的内部——但你希望有一种方法适用于所有类型的资产(例如 PNG)并且不不需要 JavaScript 编程。
  • 如果你只有一个 SGV 文件,而不是一个 svg 内联对象怎么办?
【解决方案3】:

您需要进行这样的转换:

使用 JavaScript:

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

使用 CSS:

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

将您的 SVG 页面包装在一个 Group 标签中,并以它为目标来操作整个页面:

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

注意:比例 1.0 为 100%

【讨论】:

  • 好的。我不希望 JS 在这。有没有办法让它适应父母?
  • @bj setAttribute 与 相同
  • 如果转换属性已经存在会怎样?被覆盖了?!
【解决方案4】:

四处乱逛,发现这个 CSS 似乎包含 Chrome 浏览器中的 SVG,直到容器大于图像:

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

似乎也在 FF + IE 11 中工作。

【讨论】:

  • 这为我解决了这个问题。不过,我只在 iOS 中看到了溢出。谢谢!
  • 同时使用 max-width: 100%max-height: 100% 将使 svg 始终缩放到容器,而不会溢出或丢失其纵横比。
  • @Gavin max-height: 100% 对我不起作用,通过使用 vh 而不是 % 解决
【解决方案5】:

这是最简单的方法:

类型 1: 如果您的 svg 只有一个视图框,但没有宽度和高度,像这样:

<svg viewBox="0 0 24 30">

然后你可以在 css 中指定它的大小:

svg {
  height: 80px;
}

类型 2: 如果 svg 有宽度和高度,但没有视口,像这样:

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

然后你可以手动添加一个与其宽度和高度完全相同的视图框,如下所示:

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

那么你就可以像类型 1 那样做。

【讨论】:

    【解决方案6】:

    另一个简单的方法是

    transform: scale(1.5);
    

    【讨论】:

    • 在 svg 的什么地方添加这个?这看起来 css
    • @DimitriKopriwa 在transform 属性中。例如。 &lt;g transform="scale(1.5)"&gt;...&lt;/g&gt; 或者您为元素分配 class 并使用 css。
    【解决方案7】:

    更改 SVG 文件对我来说不是一个公平的解决方案,因此我使用了relative CSS units

    vhvw% 非常方便。我使用height: 2.4vh; 之类的 CSS 为我的 SVG 图像设置动态大小。

    【讨论】:

      【解决方案8】:

      调整 currentScale 属性在 IE 中有效(我用 IE 11 测试过),但在 Chrome 中无效。

      【讨论】:

        猜你喜欢
        • 2018-09-05
        • 1970-01-01
        • 1970-01-01
        • 2012-02-13
        • 1970-01-01
        • 2018-10-11
        • 2017-06-01
        相关资源
        最近更新 更多