WebKit SVG 高度和最大高度差异

WebKit SVG height and max-height differences

如果您在 Chrome 或 Safari(Firefox 不受影响)中 运行 以下两个示例,您将看到 SVG 图像宽度的差异。

第一个示例似乎是 IMO 的正确行为。但在第二个示例中,svg 似乎被 拉伸 。那是一个错误吗?有什么解决方法吗?

示例 1 - height:100%,它按预期工作。

html, body {
  height: 100%;
  margin: 0;
}
img {
  background: silver;
  vertical-align: top;
  height: 100%;
}
<img src="https://dev.w3.org/SVG/tools/svgweb/samples/svg-files/mozilla.svg">

示例2-max-height:100%,图像的主要部分向中心移动,左右留下大量space。

html, body {
  height: 100%;
  margin: 0;
}
img {
  background: silver;
  vertical-align: top;
  max-height: 100%;
}
<img src="https://dev.w3.org/SVG/tools/svgweb/samples/svg-files/mozilla.svg">

这似乎确实是一个错误。 CSS 2.1

for replaced elements with both width and height computed as auto, use the algorithm under Minimum and maximum widths above to find the used width and height. Then apply the rules under "Computing heights and margins" above, using the resulting width and height as if they were the computed values.

在最小和最大宽度算法中,我们有这种情况:

  • 约束违规:h > max-height
  • 解析宽度:max(max-height * w/h, min-width)
  • 解析高度:max-height

由于min-width0,解析出来的宽度应该是max-height * w/h.

Webkit 似乎改用 w,所以这是一个错误。

作为解决方法,您可以使用 common technique to force an aspect ratio.

html, body {
  height: 100%;
  margin: 0;
}
#wrapper {
  position: relative;
  display: inline-block; /* Shrink-to-fit width */
  vertical-align: top;
  height: 100%;
  max-width: 100%;
  overflow: hidden;
}
.ratio {
  height: 100%;
  vertical-align: top;
  visibility: hidden;
}
.filler {
  position: absolute;
  max-height: 100%;
  max-width: 100%;
  background: silver;
  max-height: 100%;
  left: 0;
  top: 0;
}
<div id="wrapper">
  <img class="ratio" src="https://dev.w3.org/SVG/tools/svgweb/samples/svg-files/mozilla.svg">
  <img class="filler" src="https://dev.w3.org/SVG/tools/svgweb/samples/svg-files/mozilla.svg">
</div>

但是请注意,该效果仅在您加载页面时起作用。如果您随后调整 window 的大小,它将中断。要解决此问题,请使用 JS 强制重新渲染:

window.addEventListener('resize', function() {
  var el = document.getElementById('wrapper'),
      parent = el.parentNode,
      next = el.nextSibling;
  parent.removeChild(el);
  parent.insertBefore(el, next);
});
html, body {
  height: 100%;
  margin: 0;
}
#wrapper {
  position: relative;
  display: inline-block; /* Shrink-to-fit width */
  vertical-align: top;
  height: 100%;
  max-width: 100%;
  overflow: hidden;
}
.ratio {
  height: 100%;
  vertical-align: top;
  visibility: hidden;
}
.filler {
  position: absolute;
  max-height: 100%;
  max-width: 100%;
  background: silver;
  max-height: 100%;
  left: 0;
  top: 0;
}
<div id="wrapper">
  <img class="ratio" src="https://dev.w3.org/SVG/tools/svgweb/samples/svg-files/mozilla.svg">
  <img class="filler" src="https://dev.w3.org/SVG/tools/svgweb/samples/svg-files/mozilla.svg">
</div>