4

At the project I'm on we're using SVGs for icons. Most of our icons need to have a second version where the color is inverted (as in a blue icon for white background and a white icon for blue background).

We're including the icons using background-image in CSS.

I am trying to figure out if there is a way we can have only one file for each icon, and use CSS or Javascript to change it's color. That would let us get away with fewer requests.

Now, I know that using CSS to set properties on an inline SVG image works, but I don't really want to inline every icon we've got.

Is there a way to do this?

I have a Plunker where an SVG is included in three different ways. Inline, CSS background and the img tag. There's a CSS rule that sets the fill attribute and that only hits the inlined SVG. There's also a little Javascript snippet that tries to find all the circles and color them. Interestingly enough, setting fill directly on the inlined SVG does not work when fill is already set via CSS.

It seems that document.querySelectorAll will only find the inlined SVG, which I guess makes sense. The other two are strictly speaking not part of the DOM.

Now, is there any way I can override the fill of the last two circles without making changes in the circle.svg file? Is there some other trick I can use to display the circle.svg file with two different colors?

ivarni
  • 17,658
  • 17
  • 76
  • 92
  • Basically, CSS can **only** style actual elements (and pseudo elements). If your SVG aren't in the DOM...you're SOL, pretty much. – Paulie_D Apr 24 '14 at 14:05
  • That's what I was suspecting too, but the internet has surprised me before. Our designer just threw out the idea of "inverting" all the SVGs and basically use them as transparent masks over a background styled with CSS, but I don't think we'll be taking that route... – ivarni Apr 24 '14 at 14:17
  • You can inject CSS into the SVG with javascript. You may not like that solution though. – Paul LeBeau Apr 24 '14 at 14:56
  • @BigBadaboom How would I inject CSS? I can't find the SVG with `document.querySelector`. If you meant to inject CSS serverside then I would still be doing two requests per icon. – ivarni Apr 25 '14 at 05:49
  • 1
    You can't do it with images. You would need to switch to using ``. See http://stackoverflow.com/questions/4906148/how-to-apply-a-style-to-an-embedded-svg/4906603#4906603 or you could write a script to load the SVG into the DOM, modify it then turn it into a data URL and set that as your background. Both solutions are a bit ugly, which is why I said you may not like it. :) – Paul LeBeau Apr 25 '14 at 09:42
  • Right, so that's basically inlining it programmatically. You were right, I'm not a big fan but thanks for the link :) – ivarni Apr 25 '14 at 09:44
  • BTW, you probably shouldn't have "one file for every icon" anyway. Best practice is to use a sprite sheet (all icons in one image) and use `background-position` to display the correct icon. – Paul LeBeau Apr 25 '14 at 09:45
  • Yes, that was going to be the next step. Put all the icons in one SVG and use `viewBox`, but pulling that off would require the exact same solution as setting `fill` on a single image so I used that example for the question. We're trying to avoid bitmapped icons because vector-based looks so much better on high-res displays. – ivarni Apr 25 '14 at 09:46

1 Answers1

2

If you want to take a different approach to solving your problem, you can use an icon font generated from your SVG images and set the text color to white, blue or any other color. The browser must support custom fonts (@font-face) but I think most browsers that support SVG images will support this

There are a few different services that will let you create your own font like: http://icomoon.io/ or http://fontastic.me/

As an example: Bootstrap uses a subset of an icon font for their icons: http://getbootstrap.com/components/#glyphicons

Mathias
  • 5,642
  • 2
  • 31
  • 46
  • As a basic idea it's fine but icon fonts do not give you control over the various 'sections' of the SVG which seems to be the requirement. – Paulie_D Apr 24 '14 at 14:08
  • Also, the browser still treats it like text and might anti-alias the image, making it blurry. – ivarni Apr 24 '14 at 14:13
  • @Paulie_D Good point, it will only work for icons in a single color – Mathias Apr 24 '14 at 14:31