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

标签 css svg height css-grid

显然,将 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>

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

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

  • 我希望 svg 高度与表示 ShieldHealthStamina 的行的高度匹配;
  • > This question discusses this , 但:
    • 它的第一个答案建议将图像的高度设置为 1em 但尽管有绿色勾号和赞成票,这完全是错误的,即使它适用于 svg。证明如下。
    • 它的第二个答案建议明确设置行高,我想避免这种情况。原因:在整个站点中,我使用的是 font-size,例如 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>

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

最佳答案

由于使用 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 中运行良好,Chrome 能够将引用识别为文本内容的高度。

关于css - 如何将 SVG 的高度设置为其封闭容器的高度?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57895573/

相关文章:

使用 css3 动画时 HTML5 视频卡住

javascript - Internet Explorer 6 的 jQuery height() 问题

javascript - CSS 和 JavaScript 以内联方式出现在源代码中

javascript - 这种制作热图矩阵的方法正确吗

javascript - SVG 使用和 jQuery 上的 Mouseenter/Mouseleave

javascript - 我可以使用 JS 或 jQuery 来测试是否支持 SVG 图片吗?

html - 如何让字体光标位于顶部,文本对齐: top?

javascript - JS改变高度并返回原始CSS高度

html - 使用一些 css 技术以正确的格式显示 html 表格?

css - 删除 XUL menuitem 中的图像/图标空间和 menupopup 中的垂直线