51

I'm using SVG for a project, loaded in css like this:

background-image: url('data:image/svg+xml;charset=US-ASCII,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20xmlns%3Axlink%3D%22http%3A//www.w3.org/1999/xlink%22%20version%3D%221.1%22%20x%3D%220px%22%20y%3D%220px%22%20width%3D%2222px%22%20height%3D%2238px%22%20viewBox%3D%220%200%2022%2038%22%20enable-background%3D%22new%200%200%2022%2038%22%20xml%3Aspace%3D%22preserve%22%3E%3Cstyle%3E.style0%7Bfill%3A%09%23f47216%3B%7D%3C/style%3E%3Cpath%20d%3D%22M2.643%2038c-0.64%200-1.282-0.231-1.79-0.699c-1.074-0.988-1.143-2.661-0.154-3.735l13.13-14.258L0.664%204.4%20c-0.967-1.094-0.865-2.765%200.229-3.732s2.765-0.864%203.7%200.229L19.37%2017.592c0.898%201%200.9%202.545-0.035%203.542L4.588%2037.1%20C4.067%2037.7%203.4%2038%202.6%2038z%22%20class%3D%22style0%22/%3E%3C/svg%3E');

I have some hover states to highlight by changing the fill color of the arrow.

For now, I'm simply applying the same svg data with the fill portion (fill%3A%09%23f47216%3B%7D%3C where f47216 is the color) changed with the right/new color. Works pretty well. Though, I'd like to know if there's maybe some other smarter method.

Luca Reghellin
  • 7,426
  • 12
  • 73
  • 118
  • The way you're doing it is the only way you can get it to work if you're set on using background-image / data uri for your svg content. The background image is treated as just an image file, you can't change it with other CSS styles any more than you can change a PNG or JPEG file. – AmeliaBR Mar 13 '14 at 17:12

4 Answers4

28

Use filter property of CSS. For me I wanted to change the color of the icon to white on Hover:

filter: grayscale(1) brightness(2);
GorvGoyl
  • 42,508
  • 29
  • 229
  • 225
  • 15
    This didn't work for me but `filter: invert(1);` did, just fyi for future readers who are desperate like me ;-) – sn3ll Jan 29 '19 at 21:15
  • 2
    `filter: invert(1);` will only work for black. You can use `filter: brightness(0) invert(1);` for any colour. – DylanYoung Feb 21 '21 at 05:19
19

Or if you want to do it dynamically try :

var green = '3CB54A';
var red = 'ED1F24';
var svg = '<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"  width="320px" height="100px" viewBox="0 0 320 100" enable-background="new 0 0 320 100" xml:space="preserve"> <polygon class="mystar" fill="#'+green+'" points="134.973,14.204 143.295,31.066 161.903,33.77 148.438,46.896 151.617,65.43 134.973,56.679 118.329,65.43 121.507,46.896 108.042,33.77 126.65,31.066 "/><circle class="mycircle" fill="#'+red+'" cx="202.028" cy="58.342" r="12.26"/></svg>';      
var encoded = window.btoa(svg);
document.body.style.background = "url(data:image/svg+xml;base64,"+encoded+")";

Fiddle Here

tnt-rox
  • 5,400
  • 2
  • 38
  • 52
15

Base64 for that would be:

url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2ZXJzaW9uPSIxLjEiIHg9IjBweCIgeT0iMHB4IiB3aWR0aD0iMjJweCIgaGVpZ2h0PSIzOHB4IiB2aWV3Qm94PSIwIDAgMjIgMzgiIGVuYWJsZS1iYWNrZ3JvdW5kPSJuZXcgMCAwIDIyIDM4IiB4bWw6c3BhY2U9InByZXNlcnZlIj48c3R5bGU+LnN0eWxlMHtmaWxsOgkjZjQ3MjE2O308L3N0eWxlPjxwYXRoIGQ9Ik0yLjY0MyAzOGMtMC42NCAwLTEuMjgyLTAuMjMxLTEuNzktMC42OTljLTEuMDc0LTAuOTg4LTEuMTQzLTIuNjYxLTAuMTU0LTMuNzM1bDEzLjEzLTE0LjI1OEwwLjY2NCA0LjQgYy0wLjk2Ny0xLjA5NC0wLjg2NS0yLjc2NSAwLjIyOS0zLjczMnMyLjc2NS0wLjg2NCAzLjcgMC4yMjlMMTkuMzcgMTcuNTkyYzAuODk4IDEgMC45IDIuNTQ1LTAuMDM1IDMuNTQyTDQuNTg4IDM3LjEgQzQuMDY3IDM3LjcgMy40IDM4IDIuNiAzOHoiIGNsYXNzPSJzdHlsZTAiLz48L3N2Zz4=');

using a tool like http://www.base64encode.org/

This doesn't answer your question directly, but it does let us do the following. We can now test to see if:

.icon:hover .style0 {
    fill: red;
}

will work, or use

.icon {
    background-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2ZXJzaW9uPSIxLjEiIHg9IjBweCIgeT0iMHB4IiB3aWR0aD0iMjJweCIgaGVpZ2h0PSIzOHB4IiB2aWV3Qm94PSIwIDAgMjIgMzgiIGVuYWJsZS1iYWNrZ3JvdW5kPSJuZXcgMCAwIDIyIDM4IiB4bWw6c3BhY2U9InByZXNlcnZlIj48c3R5bGU+LnN0eWxlMHtmaWxsOgkjZjQ3MjE2O308L3N0eWxlPjxwYXRoIGQ9Ik0yLjY0MyAzOGMtMC42NCAwLTEuMjgyLTAuMjMxLTEuNzktMC42OTljLTEuMDc0LTAuOTg4LTEuMTQzLTIuNjYxLTAuMTU0LTMuNzM1bDEzLjEzLTE0LjI1OEwwLjY2NCA0LjQgYy0wLjk2Ny0xLjA5NC0wLjg2NS0yLjc2NSAwLjIyOS0zLjczMnMyLjc2NS0wLjg2NCAzLjcgMC4yMjlMMTkuMzcgMTcuNTkyYzAuODk4IDEgMC45IDIuNTQ1LTAuMDM1IDMuNTQyTDQuNTg4IDM3LjEgQzQuMDY3IDM3LjcgMy40IDM4IDIuNiAzOHoiIGNsYXNzPSJzdHlsZTAiLz48L3N2Zz4=');
    height: 40px;
    width: 40px;
}

.icon:hover {
    background-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2ZXJzaW9uPSIxLjEiIHg9IjBweCIgeT0iMHB4IiB3aWR0aD0iMjJweCIgaGVpZ2h0PSIzOHB4IiB2aWV3Qm94PSIwIDAgMjIgMzgiIGVuYWJsZS1iYWNrZ3JvdW5kPSJuZXcgMCAwIDIyIDM4IiB4bWw6c3BhY2U9InByZXNlcnZlIj48c3R5bGU+LnN0eWxlMHtmaWxsOglyZWQ7fTwvc3R5bGU+PHBhdGggZD0iTTIuNjQzIDM4Yy0wLjY0IDAtMS4yODItMC4yMzEtMS43OS0wLjY5OWMtMS4wNzQtMC45ODgtMS4xNDMtMi42NjEtMC4xNTQtMy43MzVsMTMuMTMtMTQuMjU4TDAuNjY0IDQuNCBjLTAuOTY3LTEuMDk0LTAuODY1LTIuNzY1IDAuMjI5LTMuNzMyczIuNzY1LTAuODY0IDMuNyAwLjIyOUwxOS4zNyAxNy41OTJjMC44OTggMSAwLjkgMi41NDUtMC4wMzUgMy41NDJMNC41ODggMzcuMSBDNC4wNjcgMzcuNyAzLjQgMzggMi42IDM4eiIgY2xhc3M9InN0eWxlMCIvPjwvc3ZnPg==');
}

which seems inefficient to me because we are forced to replicate a lot of the same information for the hover when all we want to change is the color.

working example

Jason Aller
  • 3,541
  • 28
  • 38
  • 38
  • It might be worth looking at: http://stackoverflow.com/questions/7360723/specify-an-svg-as-a-background-image-and-also-style-the-svg-in-css – Jason Aller Mar 13 '14 at 16:52
  • 1
    Although not precisely on point, this might be useful: http://css-tricks.com/svg-sprites-use-better-icon-fonts/ – Paulie_D Mar 13 '14 at 16:58
  • Ok no, it's not possible to use style0 because there's no style0 in the final svg data. So I guess my way it's the only possible. Maybe it's not really optimized but http requests are, so it's enough for me. – Luca Reghellin Mar 14 '14 at 11:10
  • to better explain: I first cleanup my svg with [this site](http://petercollingridge.appspot.com/svg_optimiser). Here there's still the style0 class you are writing about. But then I'll convert the optimized svg to base-64 in [this site](http://www.grumpicon.com/) and after this, style0 gets stripped away. – Luca Reghellin Mar 14 '14 at 11:10
  • This inefficiency will be effectively compressed by gzip or brotli – Volodymyr Bryliant Mar 31 '17 at 09:35
  • [https://codepen.io/yoksel/details/JDqvs/][1] and set color that need to change [1]: https://codepen.io/yoksel/details/JDqvs/ – Alex Sep 07 '18 at 10:13
  • first example do not work (would need to inline into HTML/DOM). Would be cool if it did work though! – user5886944 Feb 26 '21 at 09:17
6

I want to post an answer to my own question. No exactly an answer, since it doesn't imply svg as background and base64, but it's my current alternative way, much more effective if you just need mono-color icons: just use svg as css mask, and change background color. Then you can also apply transitions on mouse events. I mean something like this:

mask-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" xml:space="preserve"><path d="M11.432 9.512a.636.636 0 0 1 0 .918L2.12 19.742a.636.636 0 0 1-.458.201.637.637 0 0 1-.46-.201l-1-.998C.068 18.609 0 18.459 0 18.285s.068-.329.199-.461l7.854-7.852L.199 2.118A.638.638 0 0 1 0 1.66c0-.174.068-.327.199-.46l1-.998A.634.634 0 0 1 1.66 0c.172 0 .325.068.458.201l9.314 9.311z"/></svg>');
mask-size: auto 12px;
mask-repeat: no-repeat;
transition: background-color 200ms;
background-color: #ff0000;

Please see this fiddle for more code and demo:

https://jsfiddle.net/o25beLqj/

Also note a couple of things:

  • mask-image does not have base64 code inside. It's just preceeded by data:image/svg+xml;utf8,

  • mask css properties are quite about the same of css background properties, take a look to docs, and you'll see you can do really a lot and they can substitute background images in a variety of use cases

Luca Reghellin
  • 7,426
  • 12
  • 73
  • 118