I have the following HTML hierarchy:
div: flex 1 1 auto height=56px (modified by JS)
div: grid 1fr
svg with viewBox, width=100% height=100%
This correctly scales the svg to fit within the grid div as the top-level div's height gets changed by JS. But when there's one more level of div in there, the svg disregards the parent scale and overflows the parents:
div: flex 1 1 auto height=56px (modified by JS)
div: grid 1fr
wrapper div ***PROBLEM***
svg with viewBox, width=100% height=100%
I have a snippet below showing the behavior of the two cases. Unfortunately in my real app, I sometimes need that wrapper (it might be an <a> instead of a <div>, but that also shows the same problem). Can I somehow make that element not affect the SVG scaling algorithm?
I've reviewed resize svg wrapped in div that is wrapped in div but none of the solutions there help.
I'm looking for a pure HTML/CSS solution, since in my real code the JS resizing is happening in a framework.
I'm using recent Chrome btw.
Here's a snippet of both cases:
function resizeElt(id, h) {
const elt = document.getElementById(id)
elt.style.height = h
}
let large = false
function resize(id) {
large=!large
resizeElt(id, large ? '100px' : '50px')
}
.top {
width: 30vw;
height: 50px;
border: 1px solid blue;
display: flex;
flex: 1 1 auto;
}
.svg {
margin: auto; /* center */
display: block;
border: 1px dashed red;
}
.grid {
display: grid;
grid-template-columns: 1fr;
column-gap: 10px;
align-items: center;
width: 100%;
}
.wrapper {
}
<h3>
Show fit to width and height: SVG stays within bounds
</h3>
<button onclick="resize('top1')">
Resize container taller/shorter
</button>
<div id="top1" class="top">
<div class="inner1 grid">
<svg class="svg" height="100%" width="100%" viewBox="0 0 20 10">
<polygon fill=red stroke-width=0 points="0,10 20,10 10,0" />
<polygon fill=green stroke-width=0 points="0,10 20,10 10,5" />
</svg>
</div>
</div>
<h3>
Example 2, SVG wrapped in div, doesn't scale properly:
</h3>
<button onclick="resize('top2')">
Resize taller/shorter
</button>
<div id="top2" class="top">
<div class="inner1 grid">
<div class="wrapper">
<svg class="svg" height="100%" width="100%" viewBox="0 0 20 10">
<polygon fill=red stroke-width=0 points="0,10 20,10 10,0" />
<polygon fill=green stroke-width=0 points="0,10 20,10 10,5" />
</svg>
</div>
</div>
</div>