I have an SVG file:
myIcon.svg
<svg>.....</svg>
I want to use it in my css:
.body {
background-image: url(../myIcon.svg);
}
since an svg needs to be encoded for it to work as a background-image, that leaves me with something like this:
.body {
background-image: url("data:image/svg xml,***<here place encoded svg>***");
}
Is there a way to store the encoded svg in it's own file for maintainability? Since it's not in html tags, I'm not sure how save it to it's own file or if it's even possible.
CodePudding user response:
Put some hours in investigating which characters are not allowed in a data:image/svg
URI
Many encoders convert <
and >
, but those are valid.
Load your external SVG file and replace all invalid characters
Create a new
<style>
element with thebackground-image
Wrapped in a modern Web Component so it totally does not matter when the script is executed
⚠️ xmlns="http://www.w3.org/2000/svg"
must be present in the SVG file; it is not required when you inline SVGs in modern browsers.
<svg-import-background src="//svg-cdn.github.io/red.svg" selector="#container"></svg-import-background>
<svg-import-background src="//svg-cdn.github.io/yellow.svg" selector="div > h2"></svg-import-background>
<svg-import-background src="//svg-cdn.github.io/blue.svg" selector="pre"></svg-import-background>
<style>
body { font:16px Arial; color:beige } h2 { color: black }
</style>
<div id="container">
<h2>Web Component <svg-import-background></h2>
Inject external SVG file into CSS background-image
<pre>
<svg-import-background ATTRIBUTES:
src="PATH TO SVG FILE"
selector="Element selector"
</pre>
</div>
<script>
customElements.define("svg-import-background", class extends HTMLElement {
async connectedCallback() {
let svg = await (await fetch(this.getAttribute("src"))).text();
svg = svg.replace(/\>[\t\s\n ] \</g, "><"); // replace all BETWEEN tags
svg = svg.replace(/#/g, "#");
svg = svg.replace(/"/g, "'");
this.innerHTML = `<style>${this.getAttribute("selector") || "body"}{`
`background-image:url("data:image/svg xml;charset=UTF-8,${svg}")`
`}</style>`;
}
})
</script>
<svg viewBox="0 0 8 8"><rect width="100%" height="100%" fill="gold"></rect></svg>
Re: encodeURIComponent
Yes, you can replace all 3 replace
statements with:
svg = encodeURIComponent(svg);
The difference is what is injected in your HTML code.
The 3 replace
statements injects:
<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'><rect width='100%' height='100%' fill='#f00'></rect></svg>
encodeURIComponent
injects:
It is up to you which one you want to debug