1

I have an SVG map with 20+ areas (paths and polygons). Each area has a specific color that is set within the html of the map.

Problem is the fill color of the path(s) is being ignored because of the CSS stylesheet.

This is the CSS that is overriding it:

path {
    fill: #20487c;
}

Below is an example that shows the blue areas that are incorrect because of the CSS. I dont have access to the CSS stylesheet so I'm wondering if there is a way to correct this in the <body> of the page.

/* This is whats overidding colors*/
path {
    fill: #20487c;
}

path:hover, polygon:hover {
  fill-opacity: 1.00 !important;

}
<br/>
<h3>Blue Color areas are incorect.</h3>

<script src="https://code.jquery.com/jquery-2.2.4.min.js"></script>

<svg version="1.1" id="map-example" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
  viewBox="0 0 300 200" style="enable-background:new 0 0 300 200;" xml:space="preserve">
<path id="area_01" fill-opacity='0.5' fill="#FDE9AB" d="M90.5,72.5v12l7,1v12h20l3-27C120.5,70.5,108,77,90.5,72.5z"/>
<path id="area_02" fill-opacity='0.5' fill="#F28667" d="M89,72v14l7,1v12h21v17l-23-2l-11-6V93c0,0-6-7-16-5l5-33C72,55,80,59,89,72z"/>
<polygon id="area_03" fill-opacity='0.5' fill="#E25C56" points="120,87 119,97 119,112 138,120 155,108 155,93 136,83 "/>
<polygon id="area_04" fill-opacity='0.5' fill="#9B3D37" points="138,122 143,131 146,129 152,137 155,135 159,138 159,152 174,146 199,131 
 225,117 219,108 199,108 170,101 157,94 156.5,108.5 "/>
<path id="area 05" fill-opacity='0.5' fill="#FDE9AB" d="M122,70l-2,15l17-4l33,18l15,3l15-9l-21-29l-5,3l-17-19c0,0-16,10-22,15
 C127.9,68.9,122,70,122,70z"/>
<path id="area_06" fill-opacity='0.5' fill="#9B3D37" d="M158,47.2l16.8,18.1l4.9-3l22.7,31.2l-15.8,10L198,106l22.7,1l5.3,9l12-6l7.5-27.1
 l-4.9-20.1l-24.7-32.2c0,0-7.9-8-20.8-1l-3-3C192.1,26.6,175,36,158,47.2z"/>
<polygon id="area_07" fill-opacity='0.5' fill="#F28667" points="102,117 101,139 93,145 95,150 95,156 90,156 87,150 83,150 83,157 73,157 
 73,154 78,150 70,137 67,139 65,134 67,130 75.5,129.5 79.5,122.5 83.5,110.5 94.5,116.5 "/>
<polygon id="area_08" fill-opacity='0.5' fill="#E25C56" points="81,95 81,108 78,121 74,128 65,128 63,132 54,132 54,128 40,127 40,122 
 43,122 47,117 51,117 51,110 56,110 56,95 63,95 67,90 70,90 77,91 "/>
<polygon id="area_09" fill-opacity='0.5' fill="#9B3D37" points="104,118 119,118 119,114 135,121 142,133 146,131 151,138 147,141 141,136 
 120,150 104,137 "/>
</svg>
mwalker
  • 57
  • 2
  • 7
  • Can you add a – cjl750 Jan 18 '18 at 00:43
  • Yes. However, since there are 20 or more different areas in the actual map, and most of them have different colors. I don't know what would be the best way to override each area by using 'fill: #color '!important' . – mwalker Jan 18 '18 at 00:51
  • You can either try `:nth-child` for each different shape, or if you can modify the SVG code to give each path a different ID, you can reference the ID of each path. But right now the IDs aren't valid because there's spaces in them. You need to, for example, change `path id="area 01"` to `path id="area_01"` or `path id="area01"`. – cjl750 Jan 18 '18 at 01:00
  • Not sure what you mean by :nth-child? I edited to paths so there is not a space in the path id anymore. – mwalker Jan 18 '18 at 01:16

1 Answers1

0

The priority between SVG presentation attributes and CSS rules targeting same attributes is as follow, from less important to more important:

  • user agent default styles
  • SVG presentation attribute
  • CSS rule set in style-sheet *
  • CSS rule set in style attribute
  • CSS rule set in style-sheet with !important keyword
  • CSS rule set in style attribute with !important

* from point 3, normal CSS selector importance rules apply.

So to get a bigger importance in your markup, you can rewrite all the SVG presentation attributes as CSS rules in style attribute:

/* This is whats overidding colors*/

path {
  fill: #20487c;
}

path:hover,
polygon:hover {
  fill-opacity: 1.00 !important;
}
<br/>
<h3>No more Blue colors</h3>

<svg version="1.1" id="map-example" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 300 200" style="enable-background:new 0 0 300 200;" xml:space="preserve">
<path id="area_01" style="fill-opacity:0.5; fill:#FDE9AB" d="M90.5,72.5v12l7,1v12h20l3-27C120.5,70.5,108,77,90.5,72.5z"/>
<path id="area_02" style="fill-opacity:0.5; fill:#F28667" d="M89,72v14l7,1v12h21v17l-23-2l-11-6V93c0,0-6-7-16-5l5-33C72,55,80,59,89,72z"/>
<polygon id="area_03" style="fill-opacity:0.5; fill:#E25C56" points="120,87 119,97 119,112 138,120 155,108 155,93 136,83 "/>
<polygon id="area_04" style="fill-opacity:0.5; fill:#9B3D37" points="138,122 143,131 146,129 152,137 155,135 159,138 159,152 174,146 199,131 
 225,117 219,108 199,108 170,101 157,94 156.5,108.5 "/>
<path id="area 05" style="fill-opacity:0.5; fill:#FDE9AB" d="M122,70l-2,15l17-4l33,18l15,3l15-9l-21-29l-5,3l-17-19c0,0-16,10-22,15
 C127.9,68.9,122,70,122,70z"/>
<path id="area_06" style="fill-opacity:0.5; fill:#9B3D37" d="M158,47.2l16.8,18.1l4.9-3l22.7,31.2l-15.8,10L198,106l22.7,1l5.3,9l12-6l7.5-27.1
 l-4.9-20.1l-24.7-32.2c0,0-7.9-8-20.8-1l-3-3C192.1,26.6,175,36,158,47.2z"/>
<polygon id="area_07" style="fill-opacity:0.5; fill:#F28667" points="102,117 101,139 93,145 95,150 95,156 90,156 87,150 83,150 83,157 73,157 
 73,154 78,150 70,137 67,139 65,134 67,130 75.5,129.5 79.5,122.5 83.5,110.5 94.5,116.5 "/>
<polygon id="area_08" style="fill-opacity:0.5; fill:#E25C56" points="81,95 81,108 78,121 74,128 65,128 63,132 54,132 54,128 40,127 40,122 
 43,122 47,117 51,117 51,110 56,110 56,95 63,95 67,90 70,90 77,91 "/>
<polygon id="area_09" style="fill-opacity:0.5; fill:#9B3D37" points="104,118 119,118 119,114 135,121 142,133 146,131 151,138 147,141 141,136 
 120,150 104,137 "/>
</svg>

But of course, the best course of action would be to rewrite the guilty CSS so that it targets only the elements it is supposed to target.

Kaiido
  • 123,334
  • 13
  • 219
  • 285
  • Perfect! Just tested on actual map and works like a charm. Thank you!! – mwalker Jan 18 '18 at 01:49
  • @mwalker So you choosed css inline instead? Which is bad practice? Go figure out! – dippas Jan 18 '18 at 04:22
  • @dippas, you may not be used to data-visualization. Here the colors are quite obviously a visual representation of a numerical value (a.k.a sequential color scheme). Each entity (here region) will have its own color, based on a data-set. This is absolutely not a bad practice to use inline styles for these since each color may be unique, and generated programmatically. What could be considered bad practice here is 1. Have it hard-coded instead of generating the visualization dynamically through js & 2. Have an orphan rule like `path {...}`. But these are far beyond the scope of this question. – Kaiido Jan 18 '18 at 04:50
  • Data-attr are different then inline. Which is still a bad practice – dippas Jan 18 '18 at 08:03
  • @dippas what *Data-attr* are you talking about? OP's case is like [this mbostock's visu](https://bl.ocks.org/mbostock/4060606), except that there is a silly CSS rule in OP's page. This means that the best* fix in mbostock-itself's visu would be to use inline styles instead of the presentation attribute. (* well the "best" is obviously to remove the silly CSS rule). – Kaiido Jan 18 '18 at 08:03
  • I read data attr instead of data visualization. anyhow what days visualization has to do with using inline styles? – dippas Jan 18 '18 at 08:08
  • In that example you mentioned it is used style inside head which I did mentioned in my answer that could be a clean way to fix the issue – dippas Jan 18 '18 at 08:11
  • @dippas No, he uses the presentation attribute `fill`. Every entity has its own color, these colors are generated programmatically, just like the markup (and there is a high chance that OP does also uses some program to make its own visu). Writing up a CSS stylesheet with all these rules would make no sense. – Kaiido Jan 18 '18 at 08:13
  • You did anyway but inline. Which is bad practice. I did the same way using CSS only as op requested but in a cleaner way and better practice. And look the example you gave. It has indeed the style tag inside had with svg properties – dippas Jan 18 '18 at 08:16
  • @dippas Why would this be *bad practice*? You keep telling this without ever saying why it is. I can tell you by experience that it's easier to maintain in such a case than a stylesheet made of 3142 single rules. And for the style in the example I gave, it does just set some default rules, it doesn't set any of the path `fill` color. – Kaiido Jan 18 '18 at 08:18
  • https://stackoverflow.com/questions/2612483/whats-so-bad-about-in-line-css – dippas Jan 18 '18 at 08:21
  • @dippas So if I take the answer #1 from your link: you would create 3x more lines of code if you do indent your css `selector { \n fill: uniqueColor; \n } \n`. And as I said, this svg markup is most probably generated by a script, where a single variable would need to be changed in order to change everything in one go. – Kaiido Jan 18 '18 at 08:24
  • I've rested my case, everywhere it says it is a bad practice, and no this svg its not generated. OP did not mentioned this, you are assuming that. and read more than just the 1st answer – dippas Jan 18 '18 at 08:26
  • @dippas just like everywhere it says we should breath; but please don't when you are under water. Honestly, this answer is not only to OP, but to everyone who would come to this problem, which I stumbled upon myself more than once when dealing with SVG visualizations and st**id external plugin's CSS rules. It's a common problem for us who do data-viz as a daily job. And yes, inline CSS is one quick way. The important part of this answer being the first one about which rules takes precedence over the others. – Kaiido Jan 18 '18 at 08:34
  • again, my answer in this case (read all the options) is much cleaner and still not a bad practice, but hey OP know what OP wants. ( and yes I'm used to that kind of work too not only you ) – dippas Jan 18 '18 at 08:40
  • @dippas and which option should I read about applying the sequential color scheme in less than (3 x the number of entities) lines? – Kaiido Jan 18 '18 at 08:43
  • so for you is the number of lines the code will have? instead you inline it everyting? oh boy – dippas Jan 18 '18 at 08:44
  • @dippas I don't inline everything, I move one attribute inside an other, in the same line. And I personally don't care about lines of code no, but it's the argument of the first answer you linked to. – Kaiido Jan 18 '18 at 08:46
  • oh boy that is for a class, in this case would be for the `path` which I used in my first option, but then OP said that wanted different colors for those `path`s, now depending on which colors to which `path`s, go to my second option and use a class like the argument in the 1st answer for that link. if OP don't want to use extra markup (but OP did use to add `style` in yours) OP can still use `nth-of-type`, which I added as 3rd option, in a simplified way given I didn't know the colors for each `path` OP wanted. so yes my point stands. Inline style is a bad practice. – dippas Jan 18 '18 at 08:52
  • @dippas and then for [such a case](https://jsfiddle.net/3fxe3pjs/) you'd go until `path:nth-of-type(3142);`? Not to mention that your rules will obviously step on some other elements, since OP already has a `path{...` orphan rule, we can assume this is no the only svg in the page and even if it is now, this is just as a worth practice as inline styles. – Kaiido Jan 18 '18 at 09:02
  • In that case your inline styles is generated through JS and that's OK. Which is not Ok it is doing inline styles manually which you didn't mentioned in your answer the difference. And as you can tell this SVG is so small that I don't believe is generated. Again so we get cleared I'm against inline styles when manually done and NOT generated which you should mention in your answer. Remember to be clear in your answers for both op and (future) readers – dippas Jan 18 '18 at 09:16