【问题标题】:How to make arbitrary SVG scale up to its parent container while maintaining aspect ratio?如何在保持纵横比的同时使任意 SVG 扩展到其父容器?
【发布时间】:2026-01-08 13:30:01
【问题描述】:

我想在保持纵横比的同时将任意 SVG 放大到其父容器。请注意,我无法修改 SVG 本身,因此涉及修改 SVG 的解决方案(例如编辑其 viewBox 属性)在此处不适用。

这是一个演示问题的 JSfiddle:https://jsfiddle.net/mj9o0nea/

如果你修改窗口的大小,你会看到图像在不保持纵横比的情况下缩放。

来自 JSfiddle 的 CSS:

html {
  height: 100%;
  overflow-y: hidden !important;
  overflow-x: hidden !important;
}
body {
  height: 100%;
  margin: 0 0 0 0;
}
img {
  position: absolute;
  margin-left: auto;
  margin-right: auto;
  margin-top: auto;
  margin-bottom: auto;
  padding: 0;

  left: 5%;
  right: 5%;
  top: 3%;
  bottom: 3%;
  max-height: 94%;
  max-width: 90%;

}
.ph {
  width: 100%;
  max-width: 100%;
  max-height: 100%;
}

像 JPG 这样的普通图像可以正确显示、缩放和居中(例如 <img src=s.jpg ...),但 SVG 将无法正确显示(例如 <img src="data:image/svg+xml..."

【问题讨论】:

  • 你不能用javascript改变img src属性吗?您可以通过这种方式修改 SVG,还是您的实际图像不是真正的数据 URL?
  • 您的意思是在src 属性中添加preserveAspectRatio 属性,还是其他?据我所知,它不会对没有 viewBox 属性的 SVG 产生任何影响。也许您正在考虑其他事情?我对 SVG 不是很熟悉。
  • 我的意思是在 viewBox 属性中编辑到 src 和 preserveAspectRatio 如果你需要/想要的话。
  • 我需要知道图像的纵横比才能编写 viewBox 属性,对吧?我想我可以先解析 SVG 内容的 height 和 width 属性以计算纵横比,然后编写 viewBox 和 preserveAspectRatio 属性?
  • 这将是可行的方法,尽管您可以直接将其作为 nativeHeight 和 nativeWidth 获得。

标签: html css svg


【解决方案1】:

您需要选择当父元素的纵横比与图像的纵横比不同时会发生什么。我有forked the fiddle 来展示一种方法。为清楚起见,我省略了ph 类并将代码添加到img css。

与原始代码的不同之处在于widthheight 都是auto 以保留纵横比。由于提供了max-heightmax-width,它们将确定哪个维度填充容器。另一个维度不填充容器以保持纵横比。

您也可以通过裁剪较大的尺寸来fill the container。诀窍是提供min-heightmin-width

在 cmets 之后编辑:

正如评论中所建议的,我没有考虑到父级 (body) 的大小可能大于 img 的本机大小的可能性。在那种情况下,我想不出一个纯粹的css 解决方案。我再次分叉了小提琴here 来展示使用jQuery 的解决方案。简而言之,该脚本在加载后立即存储图像比例并设置调整大小的处理程序。该过程将次要维度设置为身体的维度,并相应地设置其他维度。

编辑纯javascript 方法:

查看纯javascript版本here

【讨论】:

  • 我正在寻找一种解决方案,可以在不裁剪的情况下扩大到父容器,同时保持纵横比。
  • 它不会扩展到父容器。
  • 其中一个维度缩放到父容器。如果两个维度都缩放到父容器,则根据定义,纵横比将与父容器的相同。如果您希望它保持纵横比,则只有一个维度可以缩放到父容器。也许我误解了你的问题。
  • 你的解释是正确的,但小提琴不是。正如您所说,它应该缩放直到一个维度与父容器一样大。但是,小提琴 jsfiddle.net/c3wyvr2q 没有按比例放大。听起来您可能正在使用非常小的屏幕? (小提琴确实从其“默认”尺寸缩小,但它不会从默认尺寸放大)。
  • 这是运行小提琴的屏幕截图。它将图像显示为容器中间的小图像,当它应该放大图像时,因为容器中显然有很多空间:imgur.com/a/Oh5Ol95