I created an SVG file that I intend to use as a background image in CSS. I want to be able to change the fill color in the SVG using a query-string parameter, like so:
#rect { background-image: url( 'rect.svg' ); }
#rect.red { background-image: url( 'rect.svg?color=red' ); }
As I understand, using a script tag in the SVG, I am able to get the color
parameter and update the fill color. Here is an example SVG:
<!DOCTYPE svg PUBLIC "-//W3C//DDTD SVG 1.1//EN" ".1/DTD/svg11.dtd">
<svg version="1.1" xmlns="">
<rect width="100%" height="100%" />
<script>
<![CDATA[
var params = { };
location.href.split( '?' )[1].split( '&' ).forEach(
function( i )
{
params[ i.split( '=' )[0] ] = i.split( '=' )[1];
}
);
if( params.color )
{
var rect = document.getElementsByTagName( "rect" )[0];
rect.setAttribute( "fill", params.color );
}
]]>
</script>
</svg>
Going to the file directly, or using an object tag seems to work, but for CSS background images or img tags, the color parameter is ignored.
I'm not exactly sure what is going on here, and I was hoping that there would be an explanation or alternative solution to what I'm trying to acplish (preferably without resorting to server-side processing).
Here is a jsFiddle showing the different render methods: /
I created an SVG file that I intend to use as a background image in CSS. I want to be able to change the fill color in the SVG using a query-string parameter, like so:
#rect { background-image: url( 'rect.svg' ); }
#rect.red { background-image: url( 'rect.svg?color=red' ); }
As I understand, using a script tag in the SVG, I am able to get the color
parameter and update the fill color. Here is an example SVG:
<!DOCTYPE svg PUBLIC "-//W3C//DDTD SVG 1.1//EN" "http://www.w3/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" xmlns="http://www.w3/2000/svg">
<rect width="100%" height="100%" />
<script>
<![CDATA[
var params = { };
location.href.split( '?' )[1].split( '&' ).forEach(
function( i )
{
params[ i.split( '=' )[0] ] = i.split( '=' )[1];
}
);
if( params.color )
{
var rect = document.getElementsByTagName( "rect" )[0];
rect.setAttribute( "fill", params.color );
}
]]>
</script>
</svg>
Going to the file directly, or using an object tag seems to work, but for CSS background images or img tags, the color parameter is ignored.
I'm not exactly sure what is going on here, and I was hoping that there would be an explanation or alternative solution to what I'm trying to acplish (preferably without resorting to server-side processing).
Here is a jsFiddle showing the different render methods: http://jsfiddle/ehb7S/
Share Improve this question asked Apr 12, 2013 at 17:02 jeffjenxjeffjenx 17.5k6 gold badges62 silver badges103 bronze badges 6- 5 javascript is disabled when SVG is used either as a CSS background image or in an image tag. – Robert Longson Commented Apr 12, 2013 at 17:17
- Ahh, that explains why it doesn't work. I'll leave this open in case there are any other clever solutions to passing parameters to the SVG via CSS, but it looks like I may be out of luck on this. – jeffjenx Commented Apr 12, 2013 at 17:57
- why not use some js outside the svg? – mihai Commented Apr 12, 2013 at 18:30
- @mihai, if you can explain to me how to manipulate the CSS background SVG from outside JavaScript, that would be helpful. – jeffjenx Commented Apr 12, 2013 at 18:34
- yeah, I've been trying to figure it out...but it's either not possible, or non-trivial :) – mihai Commented Apr 12, 2013 at 18:40
2 Answers
Reset to default 4You can use an inline SVG that is hidden, change that and dynamically encode it as a data URL that you put into the background-image
property. Your HTML could look like:
<div id="backgroundContainer" style="display:none">
<svg width="100px" height="100px" id="backgroundSvg" xmlns="http://www.w3/2000/svg">
<circle cx="50" cy="50" r="50" fill="green"/>
</svg>
</div>
<div id="divWithBackground" onclick="changeBackground(event)">
Click to change background SVG to random color
</div>
and your JavaScript like
changeBackground = function(event) {
var backgroundSvg = document.getElementById("backgroundSvg");
var backgroundContainer = document.getElementById("backgroundContainer");
backgroundSvg.getElementsByTagName("circle")[0].setAttribute(
"fill",
["red","green","blue","black"][Math.floor(4*Math.random())]
);
event.target.setAttribute(
"style",
"background-image:url(data:image/svg+xml,"
+ encodeURI(backgroundContainer.innerHTML)
+ ")"
);
}
See the proof of concept on jsFiddle.
I ended up created a server-side solution that allows me to inject the color fill into the SVG file. Essentially, I redirect all SVG requests to a PHP file that does the following on them:
$filename = $_SERVER['SCRIPT_FILENAME'];
$svg = simplexml_load_file( $filename );
if( isset( $_GET['color'] ) )
{
$svg->path->addAttribute( 'fill', '#' . $_GET['color'] );
}
header( "Content-type: image/svg+xml" );
echo $svg->asXML( );
Obviously, there's a little more to it than that, what with handling caching and such, but that's the meat-n-potatoes. Might want to check if the fill
attribute already exists, as well.