如何将 SVG 的高度设置为其封闭容器的高度?

How do I set the height of an SVG to the height of its enclosing container?

显然,将 svgheight 设置为 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.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 个 svg 以匹配线条的高度。我想我的 height: 100% 解决方案会很聪明:如果我确定 100% 指的是线的高度,将 svg 设置为 height: 100% 会给我我想要的。

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

我很惊讶,因为如果我删除 svgs 并用 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.

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

设置 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>

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

由于使用 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 一起工作正常,它能够将引用识别为文本内容的高度。