How do I properly target SVG symbol paths on hover? - css

I can't seem to properly target a symbol's path stroke when hovering.
There's a similar entry but it doesn't seem to target hovering. ( Controlling SVG colors with CSS )
In trying just to change the stroke on the use tag it just 'adds' a stroke where there wasn't one before
.terminal:hover {cursor:pointer;stroke:#000;}
When trying to target the path's themselves, it doesn't work at all
.terminal:hover path {stroke:#000;}
Does the Symbol change things for CSS targeting?
https://codepen.io/trevcis/pen/OYMLqO

Replace .terminal:hover path {stroke:#000;} with .terminal:hover use {stroke:#000;} as the actual node inside of .terminal is use, not path. It works on Chrome, FF, and Safari. Not sure about IE.
Updated answer:
If you want to use one same symbol but want to change each one's stroke color based on hover, you can try with CSS variables. Try below:
.terminal {
--color-st0: #f00; /* #54565A */
--color-st1: #0f0; /* #E2ECF5 */
}
.terminal:hover {
cursor:pointer;
}
.terminal:hover use {
--color-st0: #333333;
--color-st1: #333333;
}
.st0TERMINAL{
fill:none;
stroke: var(--color-st0);
stroke-width:6;
stroke-miterlimit:10;
}
.st1TERMINAL{
fill:none;
stroke: var(--color-st1);
stroke-width:2;
stroke-miterlimit:10;
}
.st2TERMINAL{
fill:#789904;
}
<svg id="assets" xmlns="http://www.w3.org/2000/svg" viewBox="-6 -6 200 200">
<symbol id="terminal" viewBox="0 0 16.8 16.8">
<path class="st0TERMINAL" d="M-0.8,2.6c0,0-1.8,0-1.8-1.8v-1.6c0,0,0-1.8,1.8-1.8h1.6c0,0,1.8,0,1.8,1.8v1.6c0,0,0,1.8-1.8,1.8H-0.8z"/>
<path class="st1TERMINAL" d="M-0.8,2.6c0,0-1.8,0-1.8-1.8v-1.6c0,0,0-1.8,1.8-1.8h1.6c0,0,1.8,0,1.8,1.8v1.6c0,0,0,1.8-1.8,1.8H-0.8z"/>
<path class="st2TERMINAL" d="M-0.8,2.6c0,0-1.8,0-1.8-1.8v-1.6c0,0,0-1.8,1.8-1.8h1.6c0,0,1.8,0,1.8,1.8v1.6c0,0,0,1.8-1.8,1.8H-0.8z"/>
</symbol>
<g id="terminal1" class="terminal">
<use xlink:href="#terminal" width="12" height="12" x="0" y="0" style="overflow:visible;"/>
</g>
<g id="terminal2" class="terminal">
<use xlink:href="#terminal" width="12" height="12" x="5" y="5" style="overflow:visible;"/>
</g>
</svg>

Related

SVG – :hover and links are not working in combination with clip-path and Firefox

For some reason, :hover and links are not working in combination with clip-path in Firefox. No problem with Chrome. I need clip-path to work. I know that it works without the attribute. However, it's not an option for me to remove this attribute.
Any idea why?
Simplified example:
<svg xmlns="http://www.w3.org/2000/svg" height="210" width="400">
<style>
path {
fill: blue;
}
path:hover {
fill: red;
}
</style>
<a target="_parent" href="/test">
<path id="triangle" clip-path="url('#triangle-clip')" d="M150 0 L75 200 L225 200 Z">
<title>Triangle</title>
</path>
</a>
<clipPath id="triangle-clip">
<use href="#triangle" />
</clipPath>
</svg>
We need to break the recursion here that makes the whole thing invalid. I.e. in the version in the question the clip-path points to a <use> element that points to a <path> that has a clip-path that points to a <use> that points to a <path>...
Here's one way i.e. apply the clip-path only to the path when it's a descendant of the <a> element. That's ignored by the <use> element because the selector crosses the shadow DOM boundary.
Another way would be to replace the <use> element with a copy of the <path> its pointing to and remove the clip-path from that copy of the path, and so again fix the infinite recursion problem.
<svg xmlns="http://www.w3.org/2000/svg" height="210" width="400">
<style>
path {
fill: blue;
}
path:hover {
fill: red;
}
a > path {
clip-path: url('#triangle-clip');
}
</style>
<a target="_parent" href="/test">
<path id="triangle" d="M150 0 L75 200 L225 200 Z">
<title>Triangle</title>
</path>
</a>
<clipPath id="triangle-clip">
<use href="#triangle" />
</clipPath>
</svg>
In your case clip-path does nothing, so I just removed it. ANd it's important to add #namespace.
#namespace svg url(http://www.w3.org/2000/svg);
svg|a path {
fill: blue;
}
svg|a:hover path {
fill: red;
}
<svg xmlns="http://www.w3.org/2000/svg" height="210" width="400">
<a href="/test">
<path id="triangle" d="M150 0 L75 200 L225 200 Z">
<title>Triangle</title>
</path>
</a>
</svg>
I noticed that if you open developer tools in Firefox you will see that you have a shadow-root (closed) whereas in Chrome you do not. That could possibly be why your :hover Pseudo-class isn't executing.
https://developer.mozilla.org/en-US/docs/Web/API/ShadowRoot/mode
As #Robert Longson has pointed out your initial code has a recursion issue.
Essentially, you are clipping an svg path (triangle) by itself (... that still has to be defined by itself) – resulting in the exact same shape as the 'unclipped' version.
However, since you already used the <use> element, reordering your path and clipping path definitions - avoiding unnessesary recursions – might still simplify your app's code.
<svg xmlns="http://www.w3.org/2000/svg" height="210" width="400">
<clipPath id="triangle-clip">
<path id="triangle-path" d="M150 0 L75 200 L225 200 Z" />
</clipPath>
<style>
.link-content {
fill: blue;
clip-path: url('#triangle-clip');
}
a:hover .link-content{
fill: red;
}
</style>
<a class="link" target="_parent" href="/test">
<title>Triangle</title>
<use class="link-content" href="#triangle-path" />
</a>
</svg>

clipPath transform on :focus/:hover for multiple instances of same icon

I have an SVG icon with some masked shapes comprised of:
book-1: masked by clipPath mask-1
book-2: masked by clipPath mask-2
book-3: not masked, no transform required
On :focus / :hover I want mask-1 (but not book-1), and book-2 (but not mask-2) to transform. Straightforward enough…
<a href="whatevs" class="icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 44 44">
<defs>
<style>
#book-1 {clip-path:url(#mask-1);}
#book-2 {clip-path:url(#mask-2);}
</style>
<clipPath id="mask-1">
<path class="nudge" fill="none" … />
</clipPath>
<clipPath id="mask-2">
<path fill="none" … />
</clipPath>
</defs>
<g id="book-1">
<path fill="#fff" … />
</g>
<g id="book-2">
<path fill="#fff" class="nudge" … />
</g>
<path fill="#fff" … /> <!-- book-3 -->
</svg>
</a>
/* CSS */
.icon .nudge {
transition: transform 0.2s ease-in;
}
.icon:focus .nudge,
.icon:hover .nudge {
transform: translate(-2px, 2px);
}
But the fun begins when there are multiple instances of the same icon in a page.
I have 3 Pens on CodePen, each with 2 instances of the linked icon, where:
MRYwBq fails with:
verbose code stating the full SVG each time it appears
class names for book-1 and book-2
unique id names for every instance of just the masks: mask-1 and mask-2
qwEZrG works with:
verbose code stating the full SVG each time it appears
unique id names for every instance of the books and the masks: book-1, mask-1, book-2 and mask-2
gybrvL fails with:
a <symbol> instance of the icon iterated via <use> in the page
Thoughts
This is just weird. I’d like to understand why it fails the way it does.
It’s good that this works but I would prefer not to have to iterate the IDs with JavaScript after they have been sent to the page undifferentiated.
This is what I’d like to get working, but I don’t know if that’s possible.
Since the clip-path requires an id of a svg def child, only one of these <clipPath> definitions will be taken into account in case multiple icons are placed on a page. That's why transforming the <clipPath> elements is a no-go, as all items referencing it will be affected. As a consequence, we need a solution that does not move or modify these elements based on :hover of :focus.
Fortunately, it is possible to move just the clipping path assigned to an element "without" moving the element itself by using the following trick:
Assign the clip path to the parent
Move the parent in the direction that the clip path should move
Move all children in the opposite direction
An example of this trick based on the code you provided can be found in the snippet below:
a .nudge, a .unnudge {
transition: transform 0.2s ease-in;
}
a:focus,
a:hover {
background-color: black;
}
a:focus .nudge,
a:hover .nudge {
transform: translate(-2px, 2px);
}
a:focus .unnudge,
a:hover .unnudge {
transform: translate(2px, -2px);
}
* {
box-sizing: border-box;
}
a {
display: block;
background-color: red;
padding: 0.5rem;
border-radius: 50%;
transition: background-color 0.2s ease-in;
width: 60px;
height: 60px;
}
body {
font-family: sans-serif;
line-height: 1.5;
max-width: 36em;
color: #333;
}
code {
background: #e5e5e5;
font-size: 1.125em;
border-radius: 2px;
}
<p>Instance 1:
<a href="#">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 44 44" width="44" height="44">
<defs>
<style>
.book-1{clip-path:url(#mask-1-1);}
.book-2{clip-path:url(#mask-2-1);}
</style>
<clipPath id="mask-1-1">
<path fill="none" d="M13.823,33.1V18.293a4.738,4.738,0,0,1,1.4-3.371S24.6,5.531,25.085,5.048L20.019-.019H8.143V33.1Z"/>
</clipPath>
<clipPath id="mask-2-1">
<path fill="none" d="M31.814,10.117,21.12,20.822a4.733,4.733,0,0,0-1.4,3.371V39H12V7H28.7Z"/>
</clipPath>
</defs>
<g class="nudge book-1" >
<path fill="#fff" class="unnudge" d="M22.736,5.72a1.193,1.193,0,0,0-1.686,0l-7.516,7.516a1.191,1.191,0,0,1-1.685-1.685l7.516-7.516a1.192,1.192,0,0,0-1.686-1.686L10.163,9.865h0a3.565,3.565,0,0,0-1.047,2.529h0V26.625h0a3.576,3.576,0,0,0,6.1,2.528h0l7.516-7.516a1.188,1.188,0,0,0,.349-.843V6.563A1.188,1.188,0,0,0,22.736,5.72Z"/>
</g>
<g class="book-2">
<path fill="#fff" class="nudge" d="M21.723,22.193a4.733,4.733,0,0,1,1.4-3.371l5.865-5.871v-.488a1.192,1.192,0,0,0-2.035-.843l-7.516,7.516a1.192,1.192,0,0,1-1.686-1.686l7.516-7.516a1.191,1.191,0,1,0-1.685-1.685l-7.516,7.516a3.561,3.561,0,0,0-1.048,2.528h0V32.524h0a3.577,3.577,0,0,0,6.105,2.529h0l.6-.6Z"/>
</g>
<path fill="#fff" d="M34.535,17.52a1.19,1.19,0,0,0-1.685,0l-7.516,7.516a1.192,1.192,0,0,1-1.686-1.686l7.516-7.516a1.192,1.192,0,1,0-1.686-1.685l-7.516,7.516h0a3.564,3.564,0,0,0-1.047,2.528h0V38.424h0a3.576,3.576,0,0,0,6.1,2.529h0l7.516-7.516a1.188,1.188,0,0,0,.349-.843V18.363A1.188,1.188,0,0,0,34.535,17.52Z"/>
</svg>
</a>
</p>
<p>Instance 2, exact copy of instance 1:
<a href="#">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 44 44" width="44" height="44">
<defs>
<style>
.book-1{clip-path:url(#mask-1-1);}
.book-2{clip-path:url(#mask-2-1);}
</style>
<clipPath id="mask-1-1">
<path fill="none" d="M13.823,33.1V18.293a4.738,4.738,0,0,1,1.4-3.371S24.6,5.531,25.085,5.048L20.019-.019H8.143V33.1Z"/>
</clipPath>
<clipPath id="mask-2-1">
<path fill="none" d="M31.814,10.117,21.12,20.822a4.733,4.733,0,0,0-1.4,3.371V39H12V7H28.7Z"/>
</clipPath>
</defs>
<g class="nudge book-1" >
<path fill="#fff" class="unnudge" d="M22.736,5.72a1.193,1.193,0,0,0-1.686,0l-7.516,7.516a1.191,1.191,0,0,1-1.685-1.685l7.516-7.516a1.192,1.192,0,0,0-1.686-1.686L10.163,9.865h0a3.565,3.565,0,0,0-1.047,2.529h0V26.625h0a3.576,3.576,0,0,0,6.1,2.528h0l7.516-7.516a1.188,1.188,0,0,0,.349-.843V6.563A1.188,1.188,0,0,0,22.736,5.72Z"/>
</g>
<g class="book-2">
<path fill="#fff" class="nudge" d="M21.723,22.193a4.733,4.733,0,0,1,1.4-3.371l5.865-5.871v-.488a1.192,1.192,0,0,0-2.035-.843l-7.516,7.516a1.192,1.192,0,0,1-1.686-1.686l7.516-7.516a1.191,1.191,0,1,0-1.685-1.685l-7.516,7.516a3.561,3.561,0,0,0-1.048,2.528h0V32.524h0a3.577,3.577,0,0,0,6.105,2.529h0l.6-.6Z"/>
</g>
<path fill="#fff" d="M34.535,17.52a1.19,1.19,0,0,0-1.685,0l-7.516,7.516a1.192,1.192,0,0,1-1.686-1.686l7.516-7.516a1.192,1.192,0,1,0-1.686-1.685l-7.516,7.516h0a3.564,3.564,0,0,0-1.047,2.528h0V38.424h0a3.576,3.576,0,0,0,6.1,2.529h0l7.516-7.516a1.188,1.188,0,0,0,.349-.843V18.363A1.188,1.188,0,0,0,34.535,17.52Z"/>
</svg>
</a>
</p>
Please note, that this solution is not perfect, and the trick with having two opposite movements that should sum up to no movement, can result in a bit of jerkiness of the .book-1 on some browsers (e.g. Firefox).

Filling all colors using CSS/js from a SVG

I am trying to set a fill color of a shape from an external svg that I link to inside an HTML document, so I'm using CSS/JS to style.
I'm currently only able to get a stroke to work, but that the fill seems to be overridden. Any help would be greatly appreciated
<svg style="fill:green" viewBox="0 0 1000 1000">
<!-- <image id="one" xlink:href="sears/alt1/body/willis-body.svg#body-windows-left" x="54.5" y="338"/>-->
<use style="fill:orange" class="icon" xlink:href="sears/alt1/body/willis-body.svg#body-windows-left" transform="translate(50 50)"/>
<use style="fill:orange" class="icon" xlink:href="sears/alt1/body/willis-body.svg#body-windows-left" transform="translate(350 50)"/>
</svg>
<style>
/*
#svg {
fill: none;
}
*/
use.icon:hover {
stroke: teal;
width: 100px;
fill: orange !imporant;
}
</style>
When you are going to use <use> its only taking copy of your <circle> obj as you see the code snippet you can style the <circle> and in the same time it will effect the <use>
#circle:hover {
fill: blue;
}
<svg viewBox="0 0 1000 1000">
<circle id="circle" cx="150" cy="150" r="150"/>
<use href="#circle" x="10" fill="red" transform="translate(350 50)"/>
<use href="#circle" x="10" fill="yellow" transform="translate(700 50)"/>
</svg>
and if you want to style the <use>
/* #circle:hover {
fill: blue;
} */
.new:hover {
fill: green;
}
.new2:hover {
fill: pink;
}
<svg viewBox="0 0 1000 1000" id="tr">
<circle id="circle" cx="150" cy="150" r="150"/>
<use href="#circle" x="10" class="new"fill="red" transform="translate(350 50)"/>
<use href="#circle" x="10" class="new2" fill="yellow" transform="translate(700 50)"/>
</svg>

SVG icons: Styling using CSS based on context

is it possible to style paths of SVG icons using CSS based on their context?
My SVG icon consists of 2 paths:
<g id="shape-codepen">
<path class="outer-ring" d="..."></path>
<path class="inner-logo" d="..."></path>
</g>
I use them in HTML as follow:
<svg class="shape-codepen"><use xlink:href="#shape-codepen"></use></svg>
<svg class="shape-codepen-red"><use xlink:href="#shape-codepen"></use></svg>
Basic styles:
.outer-ring { fill: #999; }
.inner-logo { fill: #666; }
But I want to change the partial color of the second one as it is in a different context, i.e.
.shape-codepen-red .outer-ring { fill: #f00; }
But is doesn't work.
Here is a simple pencode illustration my problem:
http://codepen.io/anon/pen/eZVGgv
Is it possible to change partially color of a path of an icon based on it's context? How?
No...you can't access the internal parts like that. You need two use elements. One for the ring, and a second for the inner shape.
Then address them separately.
Codepen Demo
.hide {
display: none;
}
.icon {
width: 75px;
height: 75px;
}
body {
padding: 20px;
}
.red .red {
fill: red;
}
.blue .blue {
fill: blue;
}
<svg class="hide">
<defs>
<g id="shape-codepen-ring">
<path class="outer-ring" d="M50,0C22.385,0,0,22.385,0,50c0,27.615,22.385,50,50,50c27.614,0,50-22.385,50-50C100,22.385,77.615,0,50,0z M50,91.789
C26.958,91.789,8.212,73.042,8.212,50C8.212,26.958,26.958,8.212,50,8.212c23.042,0,41.788,18.747,41.788,41.789
C91.788,73.042,73.042,91.789,50,91.789z"></path>
</g>
<g id="shape-codepen-shape">
<path class="inner-logo" d="M80.893,40.234c-0.006-0.039-0.016-0.076-0.022-0.115c-0.013-0.075-0.027-0.15-0.046-0.223
c-0.012-0.044-0.028-0.086-0.042-0.128c-0.021-0.065-0.042-0.13-0.068-0.193c-0.018-0.044-0.039-0.088-0.059-0.13
c-0.028-0.06-0.057-0.119-0.09-0.175c-0.024-0.042-0.051-0.083-0.076-0.124c-0.036-0.055-0.073-0.109-0.112-0.161
c-0.029-0.039-0.06-0.078-0.091-0.115c-0.042-0.049-0.086-0.098-0.132-0.143c-0.035-0.036-0.069-0.072-0.106-0.104
c-0.049-0.044-0.099-0.086-0.15-0.127c-0.04-0.031-0.079-0.062-0.12-0.091c-0.016-0.01-0.029-0.023-0.044-0.033L51.474,19.531
c-0.893-0.595-2.055-0.595-2.947,0L20.267,38.371c-0.015,0.01-0.028,0.023-0.044,0.033c-0.042,0.029-0.081,0.06-0.12,0.091
c-0.052,0.041-0.102,0.083-0.15,0.127c-0.037,0.032-0.071,0.068-0.106,0.104c-0.046,0.045-0.09,0.094-0.132,0.143
c-0.031,0.038-0.062,0.077-0.092,0.115c-0.039,0.052-0.076,0.106-0.111,0.161c-0.027,0.041-0.052,0.082-0.076,0.124
c-0.033,0.057-0.062,0.115-0.09,0.175c-0.021,0.042-0.042,0.086-0.06,0.13c-0.026,0.063-0.047,0.128-0.068,0.193
c-0.014,0.042-0.029,0.084-0.042,0.128c-0.02,0.073-0.032,0.148-0.046,0.223c-0.006,0.039-0.016,0.076-0.021,0.115
c-0.016,0.114-0.024,0.229-0.024,0.346V59.42c0,0.117,0.009,0.233,0.024,0.348c0.005,0.038,0.015,0.077,0.021,0.114
c0.014,0.075,0.027,0.149,0.046,0.223c0.012,0.043,0.028,0.086,0.042,0.128c0.021,0.065,0.042,0.13,0.068,0.195
c0.018,0.044,0.039,0.086,0.06,0.129c0.028,0.06,0.058,0.118,0.09,0.177c0.024,0.041,0.049,0.082,0.076,0.122
c0.035,0.056,0.072,0.109,0.111,0.161c0.029,0.041,0.061,0.078,0.092,0.115c0.042,0.049,0.086,0.098,0.132,0.144
c0.035,0.036,0.069,0.071,0.106,0.104c0.048,0.044,0.099,0.086,0.15,0.127c0.039,0.031,0.078,0.062,0.12,0.091
c0.016,0.01,0.029,0.023,0.044,0.032l28.259,18.84c0.446,0.297,0.96,0.447,1.474,0.447c0.513,0,1.027-0.149,1.473-0.447
l28.259-18.84c0.015-0.009,0.028-0.022,0.044-0.032c0.042-0.029,0.081-0.06,0.12-0.091c0.051-0.041,0.102-0.083,0.15-0.127
c0.037-0.033,0.071-0.068,0.106-0.104c0.046-0.046,0.09-0.095,0.132-0.144c0.031-0.037,0.062-0.075,0.091-0.115
c0.04-0.052,0.076-0.105,0.112-0.161c0.025-0.041,0.051-0.081,0.076-0.122c0.033-0.059,0.062-0.117,0.09-0.177
c0.02-0.042,0.041-0.085,0.059-0.129c0.026-0.065,0.047-0.13,0.068-0.195c0.014-0.042,0.03-0.085,0.042-0.128
c0.02-0.074,0.033-0.148,0.046-0.223c0.006-0.037,0.016-0.076,0.022-0.114c0.014-0.115,0.023-0.231,0.023-0.348V40.581
C80.916,40.464,80.907,40.348,80.893,40.234z M52.657,26.707l20.817,13.877l-9.298,6.221l-11.519-7.706V26.707z M47.343,26.707
v12.393l-11.518,7.706l-9.299-6.221L47.343,26.707z M24.398,45.554L31.046,50l-6.648,4.446V45.554z M47.343,73.294L26.525,59.417
l9.299-6.219l11.518,7.704V73.294z M50,56.286L40.603,50L50,43.715L59.397,50L50,56.286z M52.657,73.294V60.902l11.519-7.704
l9.298,6.219L52.657,73.294z M75.602,54.447L68.955,50l6.647-4.446V54.447z"></path>
</g>
<path id="shape-twitter" d="M100.001,17.942c-3.681,1.688-7.633,2.826-11.783,3.339
c4.236-2.624,7.49-6.779,9.021-11.73c-3.965,2.432-8.354,4.193-13.026,5.146C80.47,10.575,75.138,8,69.234,8
c-11.33,0-20.518,9.494-20.518,21.205c0,1.662,0.183,3.281,0.533,4.833c-17.052-0.884-32.168-9.326-42.288-22.155
c-1.767,3.133-2.778,6.773-2.778,10.659c0,7.357,3.622,13.849,9.127,17.65c-3.363-0.109-6.525-1.064-9.293-2.651
c-0.002,0.089-0.002,0.178-0.002,0.268c0,10.272,7.072,18.845,16.458,20.793c-1.721,0.484-3.534,0.744-5.405,0.744
c-1.322,0-2.606-0.134-3.859-0.379c2.609,8.424,10.187,14.555,19.166,14.726c-7.021,5.688-15.867,9.077-25.48,9.077
c-1.656,0-3.289-0.102-4.895-0.297C9.08,88.491,19.865,92,31.449,92c37.737,0,58.374-32.312,58.374-60.336
c0-0.92-0.02-1.834-0.059-2.743C93.771,25.929,97.251,22.195,100.001,17.942L100.001,17.942z"></path>
<g id="shape-youtube">
<path class="youtube" d="M98.77,27.492c-1.225-5.064-5.576-8.799-10.811-9.354C75.561,16.818,63.01,15.993,50.514,16
c-12.495-0.007-25.045,0.816-37.446,2.139c-5.235,0.557-9.583,4.289-10.806,9.354C0.522,34.704,0.5,42.574,0.5,50.001
c0,7.426,0,15.296,1.741,22.509c1.224,5.061,5.572,8.799,10.807,9.352c12.399,1.32,24.949,2.145,37.446,2.14
c12.494,0.005,25.047-0.817,37.443-2.14c5.234-0.555,9.586-4.291,10.81-9.352c1.741-7.213,1.753-15.083,1.753-22.509
S100.51,34.704,98.77,27.492 M67.549,52.203L43.977,64.391c-2.344,1.213-4.262,0.119-4.262-2.428V38.036
c0-2.548,1.917-3.644,4.262-2.429l23.572,12.188C69.896,49.008,69.896,50.992,67.549,52.203"></path>
</g>
</defs>
</svg>
<svg viewBox="0 0 100 100" class="icon red">
<use xlink:href="#shape-codepen-shape"></use>
<use xlink:href="#shape-codepen-ring" class="red"></use>
</svg>
<svg viewBox="0 0 100 100" class="icon blue">
<use xlink:href="#shape-codepen-shape"></use>
<use xlink:href="#shape-codepen-ring" class="blue"></use>
</svg>
Note: Chris Coyier actually covers this in his Lodge SVG course of videos

CSS3 Rotate Path within SVG Transform Origin / Firefox Issue

I'm having an issue with Firefox (43.04) and Transform Origin with the rotation of a path within an SVG element.
Instead of using the origin of the targeted Rect, it's using the center origin of the entire SVG itself. No problems in Webkit browsers.
Any suggestions?
https://jsfiddle.net/tj86Lz9g/
HTML
<a>
<svg x="0px" y="0px" viewBox="0 0 100 40">
<rect class="square" x="0" y="0" width="10" height="10"/>
<rect class="rectangle" x="20" y="0" width="30" height="10"/>
</svg>
</a>
CSS
rect {
fill:#FF0000;
}
rect.square {
transition: transform .8s ease-in-out;
transform-origin:center center;
}
a:hover rect.square {
transform:rotate(360deg);
}

Resources