0

I have this file hosted on my site:

https://commons.wikimedia.org/wiki/File:Blank_US_Map.svg

If you look inside at the SVG, there are pretty good IDs that correspond to the state's 2 letter abbreviation. That is, I go to inspect element, then URL, and see...

<path xmlns="http://www.w3.org/2000/svg" d="m 880.79902,142.42476 0.869,-1.0765 1.09022,-3.29102 -2.54308,-0.91347 -0.48499,-3.07156 -3.87985,-1.13162 -0.32332,-2.74824 -7.27475,-23.44082 -4.60142,-14.542988 -0.89708,-0.0051 -0.64664,1.616605 -0.64664,-0.484981 -0.96997,-0.969963 -1.45494,1.939925 -0.0485,5.032054 0.31165,5.667218 1.93992,2.74824 0,4.04152 -3.7182,5.06278 -2.58657,1.13164 0,1.13162 1.13163,1.77827 0,8.56802 -0.80831,9.21467 -0.16166,4.84982 0.96997,1.2933 -0.16166,4.52649 -0.48499,1.77828 0.96881,0.70922 16.78767,-4.42455 2.17487,-0.60245 1.84357,-2.77333 3.60523,-1.61312 z" id="NH" class="state"/>

I'm not trying to do anything interactive---I'd just like to color some states differently depending on a calculation, as a choropleth.

If I had a list of 3 color groups, Red, Green, Gray, and each state was in those groups, how should I collect my CSS to color this map according to that?

I tried this pure CSS, which didn't work:

#MI, #NH, #ME, #AK { 
   fill: "#ff0000";
}

#HI, #FL, #NY {
   fill: "#00FF00";
}

#CA {
   fill: "#F1F1F1"
}

I understand that I am supposed to use the SVG standard "fill" attribute rather than the CSS attribute "background-color."

Here are my other efforts using CSS+javascript on jsfiddle.

http://jsfiddle.net/7wRmX/2/

HTML:

<BODY>
    <h1>First try image</h1>
<img src="https://upload.wikimedia.org/wikipedia/commons/3/32/Blank_US_Map.svg" alt="Map of coverage across the US.">
<hr>
    <h1>Second try Object</h1>
 <object type="image/svg+xml" data="https://upload.wikimedia.org/wikipedia/commons/3/32/Blank_US_Map.svg">
  JUNK
</object>
<hr>    
    <h1>Third try Use</h1>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<use xlink:href="https://upload.wikimedia.org/wikipedia/commons/3/32/Blank_US_Map.svg"/>
</svg>
</BODY>

CSS:

.s5 {
    fill: #00FA19;
    color: #00FA19;
    background-color:#00FA19;
}

svg #NV {
    fill: #00FA19;
    color: #00FA19;
    background-color:#00FA19;    
}

hover {
  fill:red;
}

.state {
  fill: red;
}

path {
    fill: blue;
}

JAVASCRIPT:

var element = document.getElementById("CA");
element.setAttribute("class", "s5");

None of these modifications actually produce any color.

I tried a couple more things here, including using javascript to add CSS, as well as just trying to grab the element by name.

My guess in all these misadventures is I am not scoping the ID correctly? It needs to be told to look for the ID within the SVG or something? Or that it's a <path> object within the SVG?

My other guess would be I'm hosting this improperly, and the only way to style SVG is to use inline SVG? If that is the case, I'd be looking for a way to load SVG using python flask.

Community
  • 1
  • 1
Mittenchops
  • 18,633
  • 33
  • 128
  • 246

1 Answers1

1

If you want to modify the colour of an SVG file via CSS you need to link that CSS within the file itself and not from the container, either by adding a <style> element in the SVG file, a <?xml-stylesheet href="stylesheet.css" type="text/css"?> line or a html <link> element to link to an external stylesheet.

You can do it externally using javascript if you're using an <object> tag but you won't be able to make external modifications to an <image> tag.

For an <object> tag you need to get the SVG document so if you have

<object type="image/svg+xml" id="obj" data="..."/>

you could access the contents by using

document.getElementById("obj").contentDocument.getElementById("CA");
element.setAttribute("class", "s5");

but s5 would still need to be a CSS class defined within the SVG document and not within your wrapper html document.

would do that for instance. You see how you go from the <object> to its contentDocument.

There's more detail on scripting here

Robert Longson
  • 118,664
  • 26
  • 252
  • 242