SVG无法在绝对定位的父级中正确调整大小 [英] SVG fails to size properly in absolutely positioned parent

查看:72
本文介绍了SVG无法在绝对定位的父级中正确调整大小的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到一个问题,当将内联<svg>元素包装在绝对定位的父级中时,该元素不会按其viewBox属性中所声明的那样扩展到其原始大小:

I am encountering an issue where an inline <svg> element does not stretch to its native size, as declared in its viewBox attribute, when it is wrapped in an absolutely positioned parent:

  • 使用width: 100%似乎只能强制SVG扩展到浏览器定义的默认大小300px.这也会导致<img>不能调整为其原始尺寸.
  • 使用width: auto会使SVG完全折叠成0px x 0px的尺寸,但是<img>现在已调整为其原始尺寸
  • Using width: 100% seems to only force the SVG to stretch to the browser defined default size of 300px. This also causes <img> to not size to its native dimensions.
  • Using width: auto causes the SVG to collapse entirely into a dimension of 0px by 0px, but <img> is now sized to its native dimensions

有趣的是,可以通过将SVG用作<img>元素的src属性的data:image/svg+xml来复制此行为,因此看来SVG不会将其原始尺寸传递"给其包含的父对象(可以是<svg><img>元素).

Interestingly, this behavior can be replicated by using the SVG as a data:image/svg+xml for the src attribute of an <img> element, so it appears that SVG does not "pass on" its native dimensions to its containing parent (be it an <svg> or an <img> element).

所以,我的问题是CSS中是否有任何可靠的方法可以根据其viewbox属性将SVG强制调整为其原始大小.通过阅读viewBox属性和

So, my question is that if there is any reliable way in CSS that can force an SVG to size to its native size based on its viewbox attributes. I can probably use JS to brute force my way, by reading the viewBox attributes and use the fixed aspect ratio hack to show my SVG as a background image in a fixed aspect ratio <div> element, but I try to refrain from that. I am perhaps misunderstanding the browser's implementation of SVG specs, but I can't seem to find a workaround for this.

我的问题可以在下面的代码片段中复制.您可以:

My issue can be reproduced in the code snippet below. You can:

  • 使用页面顶部的复选框打开/关闭父级的绝对定位
  • <img><svg>元素上
  • 选择width声明(自动或100%)
  • turn on/off absolute positioning of the parent using a checkbox on the top of the page
  • select width declarations (auto or 100%) on the <img> or <svg> elements

// The JS logic below is only used to dynamically set styles based on checkbox/select changes, has nothing to do with SVG layout

// Change positioning strategy
document.getElementById('absPosToggle').addEventListener('change', function() {
  var parents = document.querySelectorAll('.parent');
  
  if (this.checked) {
    for (var i = 0; i < parents.length; i++) {
      parents[i].classList.remove('no-absolute-positioning');
    }
  } else {
    for (var i = 0; i < parents.length; i++) {
      parents[i].classList.add('no-absolute-positioning');
    }
  }
});

// Change width declaration of <svg>/<img> elements
document.getElementById('widthSetting').addEventListener('change', function() {
  var images = document.querySelectorAll('img, svg');
  var value = this.options[this.selectedIndex].value;
  
  if (value === '100%') {
    for (var i = 0; i < images.length; i++) {
      images[i].classList.add('width--100');
    }
  } else {
    for (var i = 0; i < images.length; i++) {
      images[i].classList.remove('width--100');
    }
  }
});

body {
  margin: 0;
  padding: 50px 0 0 0;
}

form {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  display: block;
  background-color: #fff;
  z-index: 1;
  padding: 5px;
}

.wrapper {
  width: 100%;
  height: 250px;
  background-color: #eee;
  margin-bottom: 10px;
  position: relative;
  text-align: center;
}

.parent {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

.parent.no-absolute-positioning {
  position: relative;
  top: 0;
  left: 0;
  transform: none;
}

img,
svg {
  display: block;
  width: auto;
}

img.width--100,
svg.width--100 {
  width: 100%;
}

<form>
  <label><input type="checkbox" id="absPosToggle" checked />Toggle absolute positioning</label><br />
  <label for="widthSetting">Set svg/img widths to:</label><select id="widthSetting">
    <option value="auto">Auto</option>
    <option value="100%">100%</option>
  </select>
</form>

<!-- <img> -->
<div class="wrapper">
  <div class="parent">
    <img src="https://via.placeholder.com/500x150/173755/ffffff" />
  </div>
  <span>This is an <code>&lt;img&gt;</code> element</span>
</div>

<!-- Inline <svg> -->
<div class="wrapper">
  <div class="parent">
    <svg viewBox="0 0 500 150" xmlns="http://www.w3.org/2000/svg"><rect x="0" y="0" width="500" height="150" fill="#b13131" /><g transform="translate(250, 75)"><text fill="#ffffff" style="text-anchor: middle; font-size: 50; font-family: Arial;" dy="0.35em">500 x 150</text></g></svg>
  </div>
  <span>This is an inline <code>&lt;svg&gt;</code> element</span>
</div>

<!-- <img> with SVG as data:image -->
<div class="wrapper">
  <div class="parent">
    <img src="data:image/svg+xml;charset=utf8,%3Csvg%20viewBox=%220%200%20500%20150%22%20xmlns=%22http://www.w3.org/2000/svg%22%3E%3Crect%20x=%220%22%20y=%220%22%20width=%22500%22%20height=%22150%22%20fill=%22#b13131%22%20/%3E%3Cg%20transform=%22translate(250,%2075)%22%3E%3Ctext%20fill=%22#ffffff%22%20style=%22text-anchor:%20middle;%20font-size:%2050;%20font-family:%20Arial;%22%20dy=%220.35em%22%3E500%20x%20150%3C/text%3E%3C/g%3E%3C/svg%3E" 
    />
  </div>
  <span>This is an <code>&lt;img&gt;</code> element with SVG as data:image</span>
</div>

推荐答案

我认为问题的根本原因在于,通过绝对定位,您可以使父对象的宽度计算方法变为shrink-to-fit,并且该内容和包含以下内容的内容也没有适当的固有宽度,这有点像22,这可以解释回落到标准"的300px宽度.

I think root cause of the issue is that with absolute positioning you make the width calculation method for the parent become shrink-to-fit, and with that and content that has no proper intrinsic width either, that's kind of a catch 22, which might explain the fall back to the "standard" 300px width.

我们发现,您已经通过 https://css-tricks.com/scale -svg/,并且似乎在SVG本身中添加widthheight属性可能是给SVG适当的固有高度的唯一工作方式(在这种特殊情况下),因此可以依次放大"其绝对定位的父级.

As we figured out, you have been through https://css-tricks.com/scale-svg/ already, and it seems like adding width and height attributes to the SVG itself might be the only working way (in this particular situation) to give the SVG a proper intrinsic height, so that it can in turn "span up" its absolute positioned parent.

这篇关于SVG无法在绝对定位的父级中正确调整大小的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆