Reputation: 12531
I'm trying to inline an SVG as a background image of a div
.
This works fine in a stylesheet:
div {
background-image:
url('data:image/svg+xml;charset=utf8,<svg width="30" height="25" viewBox="0 0 30 25" fill="none" xmlns="http://www.w3.org/2000/svg" version="1.1"><path d="M3 14.0204L10.8806 21L27 3" stroke="%231CDFAF" stroke-width="5" stroke-linecap="round"/></svg>');
}
As I'm using a templating language with PHP, I need to make the stroke
of the SVG dynamic. To make it dynamic, I'm trying to inline the background image SVG in the HTML style attribute but am unable to escape the "
characters in the SVG.
What I've tried:
Inlining with no escaping
<div
style="background-image: url('data:image/svg+xml;charset=utf8,<svg width="30" height="25" viewBox="0 0 30 25" fill="none" xmlns="http://www.w3.org/2000/svg" version="1.1"><path d="M3 14.0204L10.8806 21L27 3" stroke="%231CDFAF" stroke-width="5" stroke-linecap="round"/></svg>');"
>
</div>
Adding \
before each "
<div
style="background-image: url('data:image/svg+xml;charset=utf8,<svg width=\"30\" height=\"25\" viewBox=\"0 0 30 25\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\"><path d=\"M3 14.0204L10.8806 21L27 3\" stroke=\"%231CDFAF\" stroke-width=\"5\" stroke-linecap=\"round\"/></svg>');"
>
</div>
Replacing "
with %22
<div
style="background-image: url('data:image/svg+xml;charset=utf8,<svg width=%2230%22 height=%2225%22 viewBox=%220 0 30 25%22 fill=%22none%22 xmlns=%22http://www.w3.org/2000/svg%22 version=%221.1%22><path d=%22M3 14.0204L10.8806 21L27 3%22 stroke=%22%231CDFAF%22 stroke-width=%225%22 stroke-linecap=%22round%22/></svg>');"
>
</div>
Is it possible to escape this inlined SVG?
Upvotes: 3
Views: 2165
Reputation: 12531
For a more complicated SVG, you will need to escape more than just quotes.
The project I was working with is written with the Twig templating language which comes with an escape
filter which can be used with html_attr
.
For example:
<div
style="background-image: url('data:image/svg+xml;charset=utf8,{{ '<svg>...</svg>' | escape('html_attr') }}');"
>
</div>
The code for escape('html_attr')
can be found here: https://github.com/twigphp/Twig/blob/8a78e8bd20f228469cba345284ef8496f84010dd/src/Extension/CoreExtension.php#L1117
It essentially escapes any character that does not match this regex: [^a-zA-Z0-9,\.\-_]
The main characters necessary to escape are:
" "
& &
< <
> >
The following JavaScript can be used as a utility to escape an SVG string for use as a HTML attribute:
function escapeHtmlAttr(str) {
return str.replace(/["&<>]/g, char => {
switch (char) {
case '"':
return '"';
case '&':
return '&';
case '<':
return '<';
case '>':
return '>';
}
return char;
});
}
// Usage
const str = `<svg>...</svg>`; // Your SVG
const escapedStr = escapeHtmlAttr(str); // Escaped SVG
Upvotes: 0
Reputation: 46619
Use HTML escapes inside the attribute value: "
for a double quote, and (in this case not necessary, but if the need arises) '
for a single quote.
<div
style="background-image: url('data:image/svg+xml;charset=utf8,<svg width="30" height="25" viewBox="0 0 30 25" fill="none" xmlns="http://www.w3.org/2000/svg" version="1.1"><path d="M3 14.0204L10.8806 21L27 3" stroke="%231CDFAF" stroke-width="5" stroke-linecap="round"/></svg>');"
>
<br style="line-height:25px">
</div>
(Note that I had to give the div some content in order to make the background visible; otherwise its height would have been 0. But that's just for the snippet here.)
Edit: as noted in the comments, the code also works when you use %22
for quotes instead of "
.
<div
style="background-image: url('data:image/svg+xml;charset=utf8,<svg width=%2230%22 height=%2225%22 viewBox=%220 0 30 25%22 fill=%22none%22 xmlns=%22http://www.w3.org/2000/svg%22 version=%221.1%22><path d=%22M3 14.0204L10.8806 21L27 3%22 stroke=%22%231CDFAF%22 stroke-width=%225%22 stroke-linecap=%22round%22/></svg>');"
>
<br style="line-height:25px">
</div>
So could something else have gone wrong in your code? Does your div have a height?
Upvotes: 3