I was trying to develop a svg skeleton image for showing it while data is loading, here is code which I was using for editing svg.
// converting svg tag to data url and setting it as background image
const svgURL = 'data:image/svg+xml;charset=utf-8;base64,' + btoa(document.querySelector('svg').outerHTML);
document.querySelector('#xyz').style.backgroundImage = `url(${svgURL})`;
svg {
height: 48px;
}
.xyz {
background-repeat: repeat-y !important;
background-size: 100% 48px !important;
}
<svg
width="100%"
height="48"
xmlns="http://www.w3.org/2000/svg"
stroke="none"
fill="grey"
>
<circle cx="24" cy="24" r="12" />
<rect height="20" width="calc(100% - 60px)" x="48" y="14" rx="10" ry="7" fill="grey" />
</svg>
<div id="xyz" style="border: red 1px solid; height: 300px; width: 100%"></div>
As you can see same svg is rendered correctly if it is part of html, but as soon as we use it as background, width of rectangle is not setting correctly.
Any idea what I am doing wrong and how we can fix it?
CSS calc()
can still be unpredictable across different browsers when applied to SVG elements.
You may use this hack using <line>
elements instead of <rect>
.
We're defining a length via x2=100%
,
apply a translateX
transformation to shorten the line to the right
and a left x offset.
Tested in Firefox, Chrome and Safari.
// converting svg tag to data url and setting it as background image
const svgURL = 'data:image/svg+xml;charset=utf-8;base64,' + btoa(document.querySelector('svg').outerHTML);
document.querySelector('#xyz').style.backgroundImage = `url(${svgURL})`;
svg {
height: 48px;
border:1px solid #ccc;
}
.xyz {
background-repeat: repeat-y;
background-size: 100% 48px !important;
resize:both;
overflow:auto;
}
<svg
width="100%"
height="48"
xmlns="http://www.w3.org/2000/svg"
stroke="none"
fill="grey"
>
<circle cx="24" cy="24" r="12" />
<line x1="110" y1="24" x2="100%" y2="24" stroke-width="20" stroke-linecap="round" stroke="grey" style="transform:translate(-40px, 0)"></line>
</svg>
<h3>Resize me</h3>
<div class="xyz" id="xyz" style="border: red 1px solid; height: 300px; width: 100%"></div>