Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I fix cross-browser CSS issues with <use xlink>-based SVG sprite without resorting to full inline code?

SUMMARY: Some SVG-targeting CSS effects don't work in Chrome & IE (Firefox is fine) on a <use xlink> SVG sprite but the same CSS works absolutely fine when the same SVG code is truly inline.

JSFIDDLE: http://jsfiddle.net/x8vg8k4p/5/


I am currently using <svg><use xlink:href="#symbol-id" /></svg> blocks to call SVG code from an SVG sprite (as an external file) imported via PHP dynamically.

Some CSS effects are applied to the SVG, both as standard and on hover. All these effects work absolutely fine on Firefox, but on both IE and Chrome, they don't:

  • The fill attribute on the circle does not take effect
  • The opacity settings on two internal parts of the SVG (the cross by default and the thumb on hover) do not take effect

screenshot to show browser differences

I believe there is nothing wrong with the CSS as the same code works absolutely fine if the SVG code is inline and not imported via sprite id reference, which the fiddle demonstrates very clearly.

I've struggled for hours, moving bits of code around, adding and removing extra attributes, and not been able to solve this.

What follows are the relevant excerpts of the full code which can be seen on the JSfiddle link - it seems detrimental to readability to include all code here in the question, but I'm happy to edit the question if someone tells me this is bad form.

not working:

<a><svg><use xlink:href="#thumbs-up" /></svg></a>

working:

<a><svg><!-- truly inline SVG code here --></svg></a>

these parts of the CSS are the bits that fail on Chrome and IE:

a svg circle            {fill: #4291c2;}
a svg path#cross        {opacity: 0;}
a:hover svg circle      {fill: #91c142;}
a:hover svg path#cross  {opacity: 1;}
a:hover svg g#hand      {opacity: 0;}

finally the SVG code itself:

<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
    <symbol id="thumbs-up" viewBox="0 0 100 100">
        <circle cx="50" cy="50" r="50"/>
        <g id="hand">
            <polygon fill="#FFFFFF" points="64.287,37.926 64.287,71.491 80.925,71.491 73.044,37.926     "/>
            <path fill="#FFFFFF" d="M54.425,41.857c0-2.634-2.811-4.295-5.025-5.155c-2.728-1.059-4.069-4.203-1.565-8.379
                c2.146-3.58-2.084-8.795-6.628-6.058c-5.205,3.134-4.073,11.161-2.468,15.889c0.61,1.798-0.435,1.743-1.756,1.743
                c-1.081,0-5.646,0-5.646,0h-8.469c-0.998,0-3.288,6.399-2.289,6.399h10.729c-0.188,0.5-0.406,1.391-0.619,2.544H19.768
                c-1.152,0-1.919,7.2-0.714,7.2h10.859c-0.035,0.842-0.049,1.695-0.038,2.544H19.372c-1.195,0-0.277,6.256,0.803,6.256h10.413
                c0.245,0.95,0.561,1.813,0.962,2.544H21.331c-1.294,0,1.405,5.811,3.027,5.811h6.978c4.925,0,13.934,0,17.805,0
                c3.872,0,5.378-5.477,11.86-5.477V43.891C61.001,43.891,54.425,44.12,54.425,41.857z"/>
        </g>
        <path id="cross" fill="#FFFFFF" d="M50.042,54.392L39.967,66.389c-0.659,0.854-1.478,1.281-2.454,1.281
            c-0.879,0-1.612-0.306-2.198-0.915c-0.586-0.61-0.879-1.355-0.879-2.234c0-0.781,0.195-1.404,0.586-1.867l11.065-13.199
            L35.864,37.311c-0.464-0.536-0.696-1.147-0.696-1.831c0-0.806,0.286-1.531,0.859-2.179c0.572-0.646,1.31-0.971,2.211-0.971
            c1.023,0,1.852,0.382,2.485,1.145l9.285,11.188l9.547-11.273c0.586-0.706,1.318-1.06,2.198-1.06c0.781,0,1.49,0.275,2.125,0.824
            c0.635,0.55,0.953,1.251,0.953,2.105c0,0.83-0.135,1.404-0.403,1.722L54.021,49.495l10.921,13.158
            c0.415,0.463,0.623,1.041,0.623,1.729c0,0.937-0.312,1.718-0.935,2.345c-0.622,0.629-1.337,0.942-2.142,0.942
            c-0.952,0-1.782-0.427-2.49-1.282L50.042,54.392z"/>
    </symbol>
</svg>
like image 457
Matt Morrison Avatar asked Aug 08 '14 15:08

Matt Morrison


1 Answers

I think the best you can do is to use css custom properties:

:root {
  --circle-fill: #4291c2;
  --hand-fill: #ffffff;
  --cross-fill: #ffffff;
  --cross-opacity: 0;
  --hand-opacity: 1;
}

a {
  text-decoration: none; 
  display: inline-block; 
  border: none; 
  cursor: pointer; 
  position: relative; 
  width: 25px; 
  height: 25px; 
  margin: 0 2px 0 5px;
}

a, a * {
  transition: 0.2s all ease-in-out;
}

a svg {
  position: absolute; 
  left:0; 
  top:0; 
  width:100%; 
  height:100%;
}

a:hover	{
  opacity: 1.0; 
  transform: rotate(-5deg) scale(1.5);
}

a:hover .thumb {
  --circle-fill: #91c142;
  --hand-opacity: 0;
  --cross-opacity: 1;
}
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
	<symbol id="thumbs-up" viewBox="0 0 100 100">
		<circle cx="50" cy="49.999" r="50" style="fill: var(--circle-fill)"/>
		<g id="hand">
			<polygon style="fill: var(--hand-fill); fill-opacity: var(--hand-opacity)" points="64.287,37.926 64.287,71.491 80.925,71.491 73.044,37.926"/>
			<path style="fill: var(--hand-fill); fill-opacity: var(--hand-opacity)" d="M54.425,41.857c0-2.634-2.811-4.295-5.025-5.155c-2.728-1.059-4.069-4.203-1.565-8.379
				c2.146-3.58-2.084-8.795-6.628-6.058c-5.205,3.134-4.073,11.161-2.468,15.889c0.61,1.798-0.435,1.743-1.756,1.743
				c-1.081,0-5.646,0-5.646,0h-8.469c-0.998,0-3.288,6.399-2.289,6.399h10.729c-0.188,0.5-0.406,1.391-0.619,2.544H19.768
				c-1.152,0-1.919,7.2-0.714,7.2h10.859c-0.035,0.842-0.049,1.695-0.038,2.544H19.372c-1.195,0-0.277,6.256,0.803,6.256h10.413
				c0.245,0.95,0.561,1.813,0.962,2.544H21.331c-1.294,0,1.405,5.811,3.027,5.811h6.978c4.925,0,13.934,0,17.805,0
				c3.872,0,5.378-5.477,11.86-5.477V43.891C61.001,43.891,54.425,44.12,54.425,41.857z"/>
		</g>
    <path id="cross" style="fill: var(--cross-fill); fill-opacity: var(--cross-opacity)" d="M50.042,54.392L39.967,66.389c-0.659,0.854-1.478,1.281-2.454,1.281
			c-0.879,0-1.612-0.306-2.198-0.915c-0.586-0.61-0.879-1.355-0.879-2.234c0-0.781,0.195-1.404,0.586-1.867l11.065-13.199
			L35.864,37.311c-0.464-0.536-0.696-1.147-0.696-1.831c0-0.806,0.286-1.531,0.859-2.179c0.572-0.646,1.31-0.971,2.211-0.971
			c1.023,0,1.852,0.382,2.485,1.145l9.285,11.188l9.547-11.273c0.586-0.706,1.318-1.06,2.198-1.06c0.781,0,1.49,0.275,2.125,0.824
			c0.635,0.55,0.953,1.251,0.953,2.105c0,0.83-0.135,1.404-0.403,1.722L54.021,49.495l10.921,13.158
			c0.415,0.463,0.623,1.041,0.623,1.729c0,0.937-0.312,1.718-0.935,2.345c-0.622,0.629-1.337,0.942-2.142,0.942
			c-0.952,0-1.782-0.427-2.49-1.282L50.042,54.392z"/>
	</symbol>
</svg>

<a><svg><use class="thumb" xlink:href="#thumbs-up"/></svg></a>
like image 90
Der Alex Avatar answered Nov 11 '22 13:11

Der Alex