Maybe I didn’t understand fully but I think it is possible to do it like this:
Demo: https://codepen.io/Alexander9111/pen/eYNGQPz:
body {
background-color: #e9ecef;
}
.chart {
/* background: #eee; */
/* background: white; */
border: 1px solid black;
padding: 3px;
}
.chart div {
width: 0;
transition: all 1s ease-out;
-moz-transition: all 1s ease-out;
-webkit-transition: all 1s ease-out;
}
.chart div {
font: 10px sans-serif;
/* background-color: steelblue; */
background-color: #262262;
text-align: right;
padding: 3px;
margin: 5px;
color: white;
/* box-shadow: 2px 2px 2px #666; */
}
.bar {
/* fill: #262262; */
}
canvas {
display: block;
width: 100%;
visibility: hidden;
}
svg {
position: absolute;
top: 0;
left: 0;
width: 100%;
}
.graph {
width: 100%;
position: relative;
}
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css"
integrity="sha384-WskhaSGFgHYWDcbwN70/dfYBj47jz9qbsMId/iRN3ewGhXQFZCSftd1LZCfmhktB" crossorigin="anonymous">
<div id="container" class="container-fluid">
<div id="jumbotron" class="jumbotron">
<h3>SVG Chart Example</h3>
<div class="row">
<div class="col-lg-6 col-xl-4" style="padding: 10px 10px;">
<div class="card">
<h4 class="card-header">Horizontal Bars</h4>
<div class="card-body">
<div class="graph">
<canvas width="600" height="400"></canvas>
<svg viewBox="0 0 600 400" preserveAspectRatio="xMinYMin">
<g class="chart_area" transform="translate(50,0)">
<g class="chart_data">
<rect class="bar" x="0.7142857142857143" y="8" fill="rgb(110, 64, 170)" fill-opacity="0.6"
width="107.14285714285714" height="54"></rect>
<rect class="bar" x="0.7142857142857143" y="68" fill="rgb(238, 67, 149)" fill-opacity="0.6"
width="357.14285714285717" height="54"></rect>
<rect class="bar" x="0.7142857142857143" y="128" fill="rgb(255, 140, 56)" fill-opacity="0.6"
width="214.28571428571428" height="54"></rect>
<rect class="bar" x="0.7142857142857143" y="188" fill="rgb(175, 240, 91)" fill-opacity="0.6"
width="500" height="54"></rect>
<rect class="bar" x="0.7142857142857143" y="248" fill="rgb(40, 234, 141)" fill-opacity="0.6"
width="285.7142857142857" height="54"></rect>
<rect class="bar" x="0.7142857142857143" y="308" fill="rgb(47, 150, 224)" fill-opacity="0.6"
width="339.2857142857143" height="54"></rect><text class="label" y="35" font-size="12"
text-anchor="left" alignment-baseline="middle" x="112.14285714285714">300</text><text
class="label" y="95" font-size="12" text-anchor="left" alignment-baseline="middle"
x="362.14285714285717">1000</text><text class="label" y="155" font-size="12" text-anchor="left"
alignment-baseline="middle" x="219.28571428571428">600</text><text class="label" y="215"
font-size="12" text-anchor="left" alignment-baseline="middle" x="505">1400</text><text
class="label" y="275" font-size="12" text-anchor="left" alignment-baseline="middle"
x="290.7142857142857">800</text><text class="label" y="335" font-size="12" text-anchor="left"
alignment-baseline="middle" x="344.2857142857143">950</text>
</g>
<g class="x axis" font-size="10" transform="translate(0,370)" fill="none" font-family="sans-serif"
text-anchor="middle">
<path class="domain" stroke="currentColor" d="M0.5,6V0.5H500.5V6"></path>
<g class="tick" opacity="1" transform="translate(0.5,0)">
<line stroke="currentColor" y2="6"></line><text fill="currentColor" y="9" dy="0.71em">0</text>
</g>
<g class="tick" opacity="1" transform="translate(71.92857142857143,0)">
<line stroke="currentColor" y2="6"></line><text fill="currentColor" y="9" dy="0.71em">200</text>
</g>
<g class="tick" opacity="1" transform="translate(143.35714285714286,0)">
<line stroke="currentColor" y2="6"></line><text fill="currentColor" y="9" dy="0.71em">400</text>
</g>
<g class="tick" opacity="1" transform="translate(214.78571428571428,0)">
<line stroke="currentColor" y2="6"></line><text fill="currentColor" y="9" dy="0.71em">600</text>
</g>
<g class="tick" opacity="1" transform="translate(286.2142857142857,0)">
<line stroke="currentColor" y2="6"></line><text fill="currentColor" y="9" dy="0.71em">800</text>
</g>
<g class="tick" opacity="1" transform="translate(357.64285714285717,0)">
<line stroke="currentColor" y2="6"></line><text fill="currentColor" y="9" dy="0.71em">1,000</text>
</g>
<g class="tick" opacity="1" transform="translate(429.07142857142856,0)">
<line stroke="currentColor" y2="6"></line><text fill="currentColor" y="9" dy="0.71em">1,200</text>
</g>
<g class="tick" opacity="1" transform="translate(500.5,0)">
<line stroke="currentColor" y2="6"></line><text fill="currentColor" y="9" dy="0.71em">1,400</text>
</g>
</g>
<g class="y axis" font-size="10" fill="none" font-family="sans-serif" text-anchor="end">
<path class="domain" stroke="currentColor" d="M-6,0.5H0.5V370.5H-6"></path>
<g class="tick" opacity="1" transform="translate(0,35.5)">
<line stroke="currentColor" x2="-6"></line><text fill="currentColor" x="-9" dy="0.32em">Jan</text>
</g>
<g class="tick" opacity="1" transform="translate(0,95.5)">
<line stroke="currentColor" x2="-6"></line><text fill="currentColor" x="-9" dy="0.32em">Feb</text>
</g>
<g class="tick" opacity="1" transform="translate(0,155.5)">
<line stroke="currentColor" x2="-6"></line><text fill="currentColor" x="-9" dy="0.32em">Mar</text>
</g>
<g class="tick" opacity="1" transform="translate(0,215.5)">
<line stroke="currentColor" x2="-6"></line><text fill="currentColor" x="-9" dy="0.32em">Apr</text>
</g>
<g class="tick" opacity="1" transform="translate(0,275.5)">
<line stroke="currentColor" x2="-6"></line><text fill="currentColor" x="-9" dy="0.32em">May</text>
</g>
<g class="tick" opacity="1" transform="translate(0,335.5)">
<line stroke="currentColor" x2="-6"></line><text fill="currentColor" x="-9" dy="0.32em">Jun</text>
</g>
</g>
</g>
</svg></div>
</h-bars-chart>
<h5 class="card-title">Special title treatment</h5>
<p class="card-text">With supporting text below as a natural lead-in to additional content.</p>
</div>
</div>
</div>
</div>
</div>
Note that the important lines are:
CSS (see svg fills its parent element as width 100%):
svg {
position: absolute;
top: 0;
left: 0;
width: 100%;
}
Then I have the svg using viewbox and it always fills its parent div.
So you could animate this parent element’s (here the div’s) size and it should follow etc. always filling width 100%
HTML simplified example:
<div class="card-body">
<div class="graph">
<canvas width="600" height="400"></canvas>
<svg viewBox="0 0 600 400" preserveAspectRatio="xMinYMin">
</div>
</div>
Note I use a blank canvas just because otherwise in IE it doesn’t work as expected.
CSS:
canvas {
display: block;
width: 100%;
visibility: hidden;
}
Demo:
Update- 2nd iteration
After comments from the OP, I came up with a different example:
#holder {
background: #bfbfbf;
height: 98vh;
width: 98vw;
}
svg {
border: 2px solid blue;
max-height: 98vh;
}
<div id="holder">
<svg viewBox="0 0 600 400" preserveAspectRatio="xMinYMin">
<circle r="100" cx="300" cy="200" />
<circle r="10" cx="10" cy="10" />
<circle r="10" cx="10" cy="390" />
<circle r="10" cx="590" cy="10" />
<circle r="10" cx="590" cy="390" />
<rect x="0" y="0" width="600" height="400" stroke="black" stroke-width="2" fill="none" />
</div>
Demo here:
Note: the svg element’s border is blue and the rect element’s border is black, which is the set to max of the viewport, here you can see that the svg is sometimes wider than the viewport but the svg viewport is aligned/anchored top left. If you change the svg element’s preserve aspect ratio to this:
<svg viewBox="0 0 600 400" preserveAspectRatio="xMaxYMax">
Then you see the viewport aligned to the bottom right instead.
Demo also at https://codepen.io/Alexander9111/pen/rNVpWBp
UPDATE – 3rd iteration
#holder {
background: #bfbfbf;
height: 65vh;
width: 65vw;
}
svg {
border: 2px solid blue;
max-height: 80%;
}
#buttonContainer {
text-align: center;
}
<div id="holder">
<svg viewBox="0 0 600 400" preserveAspectRatio="xMinYMin">
<circle r="100" cx="300" cy="200" />
<circle r="10" cx="10" cy="10" />
<circle r="10" cx="10" cy="390" />
<circle r="10" cx="590" cy="10" />
<circle r="10" cx="590" cy="390" />
<rect x="0" y="0" width="600" height="400" stroke="black" stroke-width="2" fill="none" />
<!-- <foreignObject x="0" y="330" width="600" height="150">
<div id="buttonContainer">
<button style="height: 60px">88</button>
<button style="height: 60px">888</button>
</div>
</foreignObject> -->
<svg/>
<div id="buttonContainer">
<button style="height: 10vh">88</button>
<button style="height: 10vh">888</button>
</div>
</div>
Demo and here(https://codepen.io/Alexander9111/pen/rNVpWBp):
Note here the div with id=”holder” can be any width and height.
Then the svg css is set to max 100% height of parent element:
svg {
border: 2px solid blue;
max-height: 100%;
}