Related
I'm trying to animate the Facebook SVG icon when on hover but I can only animate separate parts of the image. Although I need to animate the whole image on hover. Here's the SVG code:
#fb-rect:hover {
fill: white;
}
#fb-path:hover {
stroke: black;
fill: black;
}
<div style="background-color: red">
<svg width="41" height="40" viewBox="0 0 41 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="fb-outer">
<rect id="fb-rect" x="1" y="0.5" width="39" height="39" stroke="white" />
<g id="fb-inner">
<path id="fb-path"
d="M22.2456 21.7899V31H18.0148V21.7899H14.5V18.0555H18.0148V16.6967C18.0148 11.6524 20.122 9 24.5806 9C25.9475 9 26.2892 9.21967 27.0377 9.39867V13.0925C26.1997 12.946 25.9638 12.8646 25.0932 12.8646C24.0599 12.8646 23.5067 13.1575 23.0022 13.7352C22.4978 14.3129 22.2456 15.3136 22.2456 16.7456V18.0636H27.0377L25.7522 21.7981H22.2456V21.7899Z"
fill="white" />
</g>
</g>
</svg>
</div>
I also have the gif demonstrating what I want to achieve:
Try this code
#fb-outer:hover #fb-rect {
fill: white;
}
#fb-outer:hover #fb-path {
stroke: black;
fill: black;
}
u can also add the position absolute:
<div style="background-color: red; position: absolute;">
I'm trying to figure out how to style an anchor tag within a SVG.
I think I've tried every variation but none seem to work as intended.
The fill works on the .logoContact a{}, so I know I'm referencing the element but the cursor property doesn't work and none of the a:hover state work.
I've tried putting the <a> within the <g class="logoEmail"> but that doesn't work. Any assistance is greatly appreciated. - CES
.logoContact a {
fill: blue;
cursor: pointer;
transition: color 1s;
}
.logoContact a:hover {
fill: red;
cursor: pointer;
transition: color 1s;
}
<g class="logoContact">
<a href="xxxx">
<g class="logoEmail">
<path d="xxxxxx" />
<path d="xxxxxx" />
<path d="xxxxxx" />
</g>
</a>
</g>
SVG elements does not have a color CSS property. Use fill or stroke instead. Here I have an example with a <rect> that changes color.
The selector is (.logoContact a) will control the fill/stroke for all child elements that does not have a more specific selector. So, in this case this effects the child <rect>.
.logoContact a {
transition: 1s fill ease-in-out;
fill: blue;
cursor: pointer;
}
.logoContact a:hover {
transition: 1s fill ease-in-out;
fill: red;
}
<svg width="100" height="100">
<g class="logoContact">
<a href="#">
<g class="logoEmail">
<rect x="0" y="0" width="100" height="100"/>
</g>
</a>
</g>
</svg>
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).
I'm following this code pen but the author's code doesn't work for my own custom SVG from Illustrator. The original author puts a fill as an inline CSS style on the SVG path code. The white hover fill won't work if I don't make the SVG path code to white.
By default - The image is invisible but should be color #788F9B.
On hover it works:
a svg:hover #bino {
fill: #fff;
}
<a href="#">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 209.84 136.85">
<path id="bino" d="M58.07,139.42a23.28,23.28,0,0,1-23.13-18.92v2.63a22.71,22.71,0,0,0,23.13,21.55A22.34,22.34,0,0,0,81.2,123.15v-2.66A22.86,22.86,0,0,1,58.07,139.42Z" transform="translate(-10.14 -29.37)" style="fill:#29aae1" />
<path d="M172.65,139.42a23.28,23.28,0,0,1-23.13-18.92v2.63a22.71,22.71,0,0,0,23.13,21.55,22.34,22.34,0,0,0,23.13-21.52v-2.66A23.28,23.28,0,0,1,172.65,139.42Z" transform="translate(-10.14 -29.37)" style="fill:#29aae1" />
<path d="M204.72,82.65h0l-43.63-47.3a29.17,29.17,0,0,0-24.18-4.2,21,21,0,0,0-16.29,21v2.63a15.35,15.35,0,0,0-4.73-1.05,14,14,0,0,0-6.31,1.58l0.53-4.2a21,21,0,0,0-16.29-21,29.75,29.75,0,0,0-23.65,4.73L25.48,83.18h0a47.88,47.88,0,1,0,80.42,35.22v-5.26a11.25,11.25,0,0,0,8.94,4.2,11.93,11.93,0,0,0,9.46-4.73v5.78a47.83,47.83,0,0,0,95.66,0A46.83,46.83,0,0,0,204.72,82.65ZM58.07,151.51a33.11,33.11,0,1,1,33.11-33.11h0a33,33,0,0,1-32.8,33.11H58.07Zm114.58,0a33.11,33.11,0,1,1,33.11-33.11h0A33,33,0,0,1,173,151.51h-0.32Z" transform="translate(-10.14 -29.37)" style="fill:#fff" />
</svg>
</a>
It doesn't work because the style attributes in HTML have precedence over the CSS stylesheet. Hence the color never changes.
You can solve this by defining the initial color in your stylesheet instead:
#bino {
fill: #29aae1;
}
a:hover #bino {
fill: #fff;
}
A working example:
a {
display: block;
width: 166px;
padding: 30px;
}
a:hover {
background-color: #166584;
}
.bino {
fill: #29aae1;
}
#binocular {
fill: #788F9B;
}
a:hover #binocular {
fill: #fff;
}
<a href="#">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 209.84 136.85">
<path class="bino" d="M58.07,139.42a23.28,23.28,0,0,1-23.13-18.92v2.63a22.71,22.71,0,0,0,23.13,21.55A22.34,22.34,0,0,0,81.2,123.15v-2.66A22.86,22.86,0,0,1,58.07,139.42Z" transform="translate(-10.14 -29.37)" />
<path class="bino" d="M172.65,139.42a23.28,23.28,0,0,1-23.13-18.92v2.63a22.71,22.71,0,0,0,23.13,21.55,22.34,22.34,0,0,0,23.13-21.52v-2.66A23.28,23.28,0,0,1,172.65,139.42Z" transform="translate(-10.14 -29.37)" />
<path id="binocular" d="M204.72,82.65h0l-43.63-47.3a29.17,29.17,0,0,0-24.18-4.2,21,21,0,0,0-16.29,21v2.63a15.35,15.35,0,0,0-4.73-1.05,14,14,0,0,0-6.31,1.58l0.53-4.2a21,21,0,0,0-16.29-21,29.75,29.75,0,0,0-23.65,4.73L25.48,83.18h0a47.88,47.88,0,1,0,80.42,35.22v-5.26a11.25,11.25,0,0,0,8.94,4.2,11.93,11.93,0,0,0,9.46-4.73v5.78a47.83,47.83,0,0,0,95.66,0A46.83,46.83,0,0,0,204.72,82.65ZM58.07,151.51a33.11,33.11,0,1,1,33.11-33.11h0a33,33,0,0,1-32.8,33.11H58.07Zm114.58,0a33.11,33.11,0,1,1,33.11-33.11h0A33,33,0,0,1,173,151.51h-0.32Z" transform="translate(-10.14 -29.37)" />
</svg>
</a>
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