简体   繁体   English

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

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

Apparently, setting the svg 's height to 100% doesn't always work. 显然,将svgheight设置为100%并不总是可行。

Consider the following snippet: 考虑以下代码段:

 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> 

My intention was to set these 3 svg s to match the height of the lines. 我的意图是将这3个svg设置为与线条的高度匹配。 I thought I'd be clever with my height: 100% solution: If I made certain that 100% referred to the height of the line, setting the svg to height: 100% would give me what I wanted. 我以为自己会比较聪明height: 100%解决方案:如果我确定100%指线条的高度,则将svg设置为height: 100%会给我我想要的东西。

Sadly, as you can see above, this wont work. 可悲的是,正如您在上面看到的那样,这将行不通。 The svgs are enormous. svg很大。

I am surprised because if I remove the svgs and replace them with spans this suddenly starts working exactly as expected: 我很惊讶,因为如果我删除了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> 

Why do svg s not obey height: 100% , even though span s do obey this? 为什么svg不能遵循height: 100% ,即使span遵循这个height: 100% How can I make the svg s height match the height of the enclosing container anyway? 无论如何,如何使svg的高度与封闭容器的高度匹配? That is, while making certain the enclosing container's height matches the height of the line - I don't want to set the height of the text ('Stamina', 'Shield', 'Health') explicitely to eg 10px . 也就是说,在确定封闭容器的高度与行的高度匹配的同时,我不想将文本的高度(“ Stamina”,“ Shield”,“ Health”)显式设置为例如10px

Appendix: Why I want it and research I've done 附录:为什么要我做我做过的研究

  • I want the svg height to match the height of the line that says Shield , Health , Stamina ; 我希望svg高度与表示ShieldHealthStamina的线的高度匹配;
  • This question discusses this , but: 这个问题对此进行了讨论 ,但是:
    • Its first answer suggests setting the image's height to 1em but despite the green tick and upvotes this is simply wrong, even though it works with svg s. 它的第一个答案建议将图像的高度设置为1em但是尽管有绿色的勾号和赞成,但这是错误的,即使它与svg一起使用也是如此。 Proof below. 下面的证明。
    • Its second answer suggests explicitely setting the line height, which I'd like to avoid. 第二个答案建议明确设置行高,这是我要避免的。 Reason: Throughout the site I'm using font-size s like smaller . 原因:在整个站点中,我都使用诸如smaller font-size
  • Another question that discusses it . 讨论它的另一个问题 It has 3 answers: 它有3个答案:
    • First suggests setting the svg as abackground image - I don't want it since I want to generate the svg via JS; 首先建议将svg设置为背景图片-我不需要,因为我想通过JS生成svg
    • Second once again suggest explicitly setting the line height 其次再次建议明确设置线条高度
    • Third answer wants to use flexbox but I want to use grid for the reason that I want the division into 2 columns. 第三个答案要使用flexbox,但由于要将其分为2列,因此我想使用grid。

Proof that setting to 1em won't work: 证明设置为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> 

As you can see there are white gaps between the bars. 如您所见,条形图之间存在白色间隙。

Since it works fine using span, consider the SVG inside the span element. 由于使用span可以正常工作,因此请考虑span元素内的SVG。 Note the use of height:0;min-height:100% to avoid creating a cycle with height:100% . 请注意,使用height:0;min-height:100%可以避免创建一个height:100%的循环。 So we set the height to 0 (it won't affect the height of the parents) then we force it to 100% using min-height (we already have the height of the parent element) 因此我们将高度设置为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> 

In your code you are facing an issue related to percentage height where the reference isn't explicetely defined so it's failling to auto. 在您的代码中,您面临一个与百分比高度相关的问题,在该高度中未明确定义引用,因此无法自动执行。 Note that it's working fine with Chrome which is able to identify the reference to be the height of the text content. 请注意,它可以与Chrome一起正常使用,Chrome可以将引用标识为文本内容的高度。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM