【问题标题】:How do I set the height of an SVG to the height of its enclosing container?如何将 SVG 的高度设置为其封闭容器的高度?
【发布时间】:2019-09-11 19:19:32
【问题描述】:

显然,将svgheight 设置为100% 并不总是有效。

考虑以下 sn-p:

function createBar(color) {
	const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg')
  
  const rect = document.createElementNS('http://www.w3.org/2000/svg', 'rect')
  svg.appendChild(rect)
  rect.setAttribute('height', '100%')
  rect.setAttribute('width', '100%')
  rect.setAttribute('fill', color)
  
  return svg
}

document.getElementById('health').appendChild(createBar('crimson'))
document.getElementById('stamina').appendChild(createBar('orange'))
document.getElementById('shield').appendChild(createBar('teal'))
ul {
  display: grid;
  list-style-type: none;
  padding: 0;
  grid-template-columns: max-content 1fr;
}

li {
  display: contents;
}

svg {
  width: 100%;
  height: 100%;
  display: inline;
}
<ul>
<li id="health"><span>Health: </span></li>
<li id="stamina"><span>Stamina: </span></li>
<li id="shield"><span>Shield: </span></li>
</ul>

我的意图是设置这 3 个 svgs 以匹配线条的高度。我认为我的height: 100% 解决方案会很聪明:如果我确定100% 指的是线的高度,将svg 设置为height: 100% 会给我想要的。

遗憾的是,正如您在上面看到的,这行不通。 svg 是巨大的。

我很惊讶,因为如果我删除 svg 并用 spans 替换它们,这会突然开始完全按预期工作:

ul {
  display: grid;
  list-style-type: none;
  padding: 0;
  grid-template-columns: max-content 1fr;
  grid-template-rows: max-content;
}

li {
  display: contents;
}

span:last-child {
  width: 100%;
  background-color: red;
  height: 100%;
}
<ul>
<li><span>Health: </span><span style="background-color: crimson;"></span></li>
<li><span>Stamina: </span><span style="background-color: orange;"></span></li>
<li><span>Shield: </span><span style="background-color: teal;"></span></li>
</ul>

为什么svgs 不服从height: 100%,即使spans 确实服从这个?无论如何,我怎样才能使svgs 的高度与封闭容器的高度相匹配?也就是说,在确保封闭容器的高度与行的高度匹配的同时 - 我不想将文本的高度('Stamina'、'Shield'、'Health')明确设置为例如 10px.

附录:我为什么想要它以及我所做的研究

  • 我希望svg 的高度与表示ShieldHealthStamina 的行的高度相匹配;
  • This question discusses this,但是:
    • 它的第一个答案建议将图像的高度设置为1em,但尽管有绿色勾号和赞成票,这完全是错误的,即使它适用于svgs。证明如下。
    • 它的第二个答案建议明确设置行高,我想避免这样做。原因:整个网站我都在使用font-sizes,比如smaller
  • Another question that discusses it。它有3个答案:
    • 首先建议将svg 设置为背景图片——我不想要它,因为我想通过JS 生成svg
    • 再次建议明确设置行高
    • 第三个答案想使用 flexbox,但我想使用网格,因为我希望将其划分为 2 列。

证明1em 的设置不起作用:

function createBar(color) {
	const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg')
  
  const rect = document.createElementNS('http://www.w3.org/2000/svg', 'rect')
  svg.appendChild(rect)
  rect.setAttribute('height', '100%')
  rect.setAttribute('width', '100%')
  rect.setAttribute('fill', color)
  
  return svg
}

document.getElementById('health').appendChild(createBar('crimson'))
document.getElementById('stamina').appendChild(createBar('orange'))
document.getElementById('shield').appendChild(createBar('teal'))
ul {
  display: grid;
  list-style-type: none;
  padding: 0;
  grid-template-columns: max-content 1fr;
}

li {
  display: contents;
}

svg {
  width: 100%;
  height: 1em;
  display: inline;
}
<ul>
<li id="health"><span>Health: </span></li>
<li id="stamina"><span>Stamina: </span></li>
<li id="shield"><span>Shield: </span></li>
</ul>

如您所见,条形之间有白色间隙。

【问题讨论】:

  • 哪个浏览器?第一个 sn-p 在 Chrome 上运行良好
  • @TemaniAfif 是吗?我很惊讶。我在火狐上。
  • 是的,只有 firefox 失败.. 作为旁注,最后一个 sn-p 中的高度需要为 1.2em 才能具有完整高度,因为 line-height 默认设置为 1.2
  • @TemaniAfif 1.2?不知道这个。是不是操作系统/浏览器/用户的主题/用户的字体/等依赖?
  • 这里:developer.mozilla.org/en-US/docs/Web/CSS/line-height#Values .. 它大致是默认值 normal ... 当然请注意大致,因此作为解决方案并不可靠,但可能会工作

标签: css svg height css-grid


【解决方案1】:

由于使用 span 可以正常工作,因此请考虑 span 元素内的 SVG。请注意使用height:0;min-height:100% 以避免使用height:100% 创建循环。所以我们将高度设置为 0(它不会影响父元素的高度)然后我们使用 min-height 将其强制为 100%(我们已经有了父元素的高度)

function createBar(color) {
	const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg')
  
  const rect = document.createElementNS('http://www.w3.org/2000/svg', 'rect')
  svg.appendChild(rect)
  rect.setAttribute('height', '100%')
  rect.setAttribute('width', '100%')
  rect.setAttribute('fill', color)
  
  return svg
}

document.querySelector('#health span:last-child').appendChild(createBar('crimson'))
document.querySelector('#stamina span:last-child').appendChild(createBar('orange'))
document.querySelector('#shield span:last-child').appendChild(createBar('teal'))
ul {
  display: grid;
  list-style-type: none;
  padding: 0;
  grid-template-columns: max-content 1fr;
}

li {
  display: contents;
}


span:last-child{
  display:block;
  width: 100%;
  height: 100%;
}
svg {
  display:block;
  height:0;
  min-height:100%;
  width: 100%;
}
<ul>
<li id="health"><span>Health: </span><span></span></li>
<li id="stamina"><span>Stamina: </span><span></span></li>
<li id="shield"><span>Shield: </span><span></span></li>
</ul>

在您的代码中,您面临与百分比高度相关的问题,其中没有明确定义参考,因此无法自动。请注意,它与 Chrome 一起工作正常,它能够将引用识别为文本内容的高度。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-18
    • 1970-01-01
    • 2015-03-18
    • 2016-01-20
    • 2013-04-08
    • 2017-12-26
    相关资源
    最近更新 更多