SVG opacity animation on hover with CSS - html

I have SVG which contain two rings: inner and outer. I'm trying to create an animation, where svg on hovered shows inner ring instantly, and outer after 300ms.
I've tried with keyframes animation, but apparently I cannot trigger child element animation when parent is hovered. See this pen.

The problem was that you were triggering the keyframe animation on the <svg> element itself, then telling one of the elements inside it to have a delayed animation.
You can only add properties like animation-delay on the elements being animated, so I moved the animation to the <circle> elements. Here you go:
svg {
width: 202px;
height: 202px;
}
svg:hover circle {
animation: show-inner 1s;
}
svg circle.ring-outer {
animation-delay: 300ms;
}
#keyframes show-inner {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
<svg viewbox="0 0 202 202" preserveAspectRatio="xMidYMid meet" version="1.1" xmlns="http://www.w3.org/2000/svg">
<circle cx="101" cy="101" r="100" stroke="#7b82c7" stroke-width="1" fill="none" class="ring-outer"/>
<circle cx="101" cy="101" r="76" stroke="#7b82c7" stroke-width="1" fill="none" class="ring-inner"/>
</svg>

Related

Drop shadow with fade in animation is cut off on iOS

I have a website where I fade in a set of SVG icons which have the filter: drop-shadow rule applied. This works fine on desktop, however on iOS the shadow gets cut off once the animation finishes.
For example, this is the html:
<div class="fade-in">
<svg class="shadow" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
<circle cx="50" cy="50" r="50" fill="white"/>
</svg>
</div>
The css:
#keyframes fade-in {
from {
opacity: 0.0;
}
to {
opacity: 1.0;
}
}
.fade-in {
animation: fade-in 2s;
}
.shadow {
filter: drop-shadow(0 0.1rem 0.7rem black);
}
JS Bin:
https://jsbin.com/yonifusomo/edit?html,css,output
Result on iOS after the animation finishes:
Safari has multiple bugs related to shadows and various animations. Luckily, looks like this one is not the worst. Adding a -webkit-transform: translateZ(0); property to your .fade-in class did the trick for me.
For more info: this post is pretty similar to yours, and it contains almost same advice.

Animate element of svg image in css

I am trying to animate some elements of an image in svg. To test the animation I first tried it on the whole image to check that it works well (it does). But when I change the class state-indicator-illustration by the id note-double-1 (id of the element to animate) the element note-double 1 disappears completely without me understanding why.I specify that to test I inserted the image "line by line" in the HTML code.
Here is the code (i put jsfiddle to avoid very long message) :
JsFiddle: https://jsfiddle.net/pju2ateL/2/
Thanks for your help,
elshiri.
As I've commented: you need to remove the transform attribute of the path.
In order to preserve your transformations I am wrapping the path in a group and transform the group instead of transforming the path. Also I had to change the viewBox since otherwise the path falls outside the svg canvas.
As you can see the css animation is working.
/* .state-indicator-illustration is working */
#note-double-1 {
/*overflow: hidden;*/
transform: translateY(0px);
animation: float 6s ease-in-out infinite;
}
#keyframes float {
0% {
transform: translateY(0px);
}
50% {
transform: translateY(-20px);
}
100% {
transform: translateY(0px);
}
}
<svg xmlns="http://www.w3.org/2000/svg" width="244" height="149.388" viewBox="-15 -320 244 149.388">
<g id="off" transform="translate(-1090, -390)">
<g transform="translate(-28.904 -320.214)" >
<path id="note-double-1" d="M1114.926,434.328l5.138-22.688,22.647,1.41c-.05.226-.093.412-.133.6q-2.918,12.882-5.824,25.761a5.089,5.089,0,0,1-3.018,3.727,7.907,7.907,0,0,1-9.016-2.153c-2.277-2.776-1.476-6.41,1.8-7.774a7.7,7.7,0,0,1,8.184,1.341c.1.083.205.172.31.245h.067l3.237-14.3c-1.28-.081-2.527-.164-3.772-.245-4.355-.272-8.713-.535-13.066-.821-.412-.029-.524.113-.61.49-1.4,6.229-2.861,12.445-4.2,18.686a5.393,5.393,0,0,1-4.558,4.48,7.783,7.783,0,0,1-8.129-3.455,4.664,4.664,0,0,1,1.414-6.408,7.077,7.077,0,0,1,6.186-.777,8.54,8.54,0,0,1,1.767.758A17.8,17.8,0,0,1,1114.926,434.328Z"/>
</g>
</g>
</svg>

How to animate the fill color of SVG with CSS?

CSS allows to change the color of SVG like this
.clr {fill: green;}
But when I apply animation with the same fill attributes nothing seems to work. What should I do?
<svg width="800" height="600" style="background-color:lightblue">
<circle class="clr" cx="610" cy="240" r="4" fill="gold" />
<style>
.clr {animation: col 3s linear infinite;}
#keyframes col {
0%,71% {fill:none}
72% {fill:black}
75%,100% {fill:none}
}
</style>
</svg>
Its working as expected, I just increased the circle radius and changed its position to show it on 50x and 50y,
.color {animation: col 3s linear infinite;}
#keyframes col {
0%,71% {fill:none}
72% {fill:black}
75%,100% {fill:none}
}
<svg width="800" height="600" style="background-color:lightblue">
<circle class="color" cx="50" cy="50" r="30" fill="gold" />
</svg>
You Just add fill:black in #keyframes section. change it to green like this:
.color {animation: col 3s linear infinite;}
#keyframes col {
0%,71% {fill:none}
72% {fill:green}
75%,100% {fill:none}
}
<svg width="800" height="600" style="background-color:lightblue">
<circle class="color" cx="610" cy="240" r="4" fill="gold" />
</svg>
and don't want to use .color {fill: green;}.
You cannot animate from none (nothing) to green (something) for a smooth transition. Instead do:
#keyframes col {
0%, 71% { fill: none; } /* change attribute value to `inherit` */
72% { fill: black; }
75%, 100% { fill: none; } /* or change value to `currentcolor` */
}
Resulting in the following:
#keyframes col {
0%, 71% { fill: inherit; }
72% { fill: black; }
75%, 100% { fill: currentcolor; }
}
Then play around with the animation attribute or element.animate to achieve desired effect.
Following is the example from #Muhammad (because it is easier to see than the OP's example of a small dot in the lower right) of an svg with an inline style section. As I read the specification, it should work as is. However, browser support still seems to be lacking 3 years later, now in 2020.
SVG 2 Requirement: Add HTML5 ‘style’ element attributes to SVG's ‘style’ element.
Resolution: SVG 2 ‘style’ element shall be aligned with the HTML5 ‘style’ element.
Purpose: To not surprise authors with different behavior for the ‘style’ element in HTML and SVG content.
I have used VS Code with a plugin called jock.svg and the animation works as expected in the live preview pane. Just copy and save the svg code "as is" with a file extension of "svg".
It is hard to know what animation the OP was going for without a description because the code snippet is said to be not working.
For clarity I will describe what this example does: It displays a briefly (3% of the time) flashing black circle on a light blue background in the top left corner. Note that the original "gold" fill is ignored when the animation is working. Today in Safari (Mac, iPad), Chrome (iPad) and Edge (iPad), all I see is the "gold" circle. No animation is applied. Please comment if (when) your browser works. I suspect this hole in browser support will be filled in the future.
[Edit]
It works in Chrome 81.0.4044.92 (Mac)
<svg width="800" height="600" style="background-color:lightblue">
<circle class="color" cx="50" cy="50" r="30" fill="gold" />
<style>
.color {animation: col 3s linear infinite;}
#keyframes col {
0%,71% {fill:none}
72% {fill:black}
75%,100% {fill:none}
}
</style>
</svg>

svg sprite in css - is transform scale legit way of scaling

Im using SVG sprite as a CSS background image like this:
.icon-arrow-down-dims {
background: url("../sprite/css-svg-sprite.svg") no-repeat;
background-position: 16.666666666666668% 0;
width: 32px;
height: 32px;
display: inline-block;
}
The only way I could scale that and that it works as expected is to use transform: scale(2) to make it 2 times bigger or transform: scale(.5) to make it two times smaller.
.icon-arrow-down-dims {
#extend %svg-common;
background-position: 16.666666666666668% 0;
width: 32px;
height: 32px;
display: inline-block;
transform: scale(2);
}
That really does scale it and it works because its not pixelated like png sprites.
My question is: is that a legit way of scaling svg css sprite? Are there any other ways to achieve it? Thanks in advance
Why just not using width and height for scalling?
Your way of scaling is not wrong, but I am not sure if it will be compatible with every browser.
Here is an example.
.icon {
background-size: auto 100% !important;
display:inline-block;
}
.icon.small {
height: 1em;
width: 1em;
}
.icon.large {
height: 2em;
width: 2em;
}
.icon_1 {
background: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="64" height="16" viewBox="0 0 64 16"> <circle fill="blue" cx="8" cy="8" r="8"/> <circle fill="red" cx="24" cy="8" r="8"/> <circle fill="yellow" cx="40" cy="8" r="8"/> <circle fill="green" cx="56" cy="8" r="8"/> </svg>') 100% 0 no-repeat;
}
.icon_2 {
background: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="64" height="16" viewBox="0 0 64 16"> <circle fill="blue" cx="8" cy="8" r="8"/> <circle fill="red" cx="24" cy="8" r="8"/> <circle fill="yellow" cx="40" cy="8" r="8"/> <circle fill="green" cx="56" cy="8" r="8"/> </svg>') 33.33% 0 no-repeat;
}
Edit
The above example will not work if you dont specify viewBox. Thanks #RobertLongson
The transform attribute defines a list of transform definitions that are applied to an element and the element's children
Now look, transform = scale(2) will work great until you dont have a children to that div element that has your svg, if you do have a child than it will be scaled too. However if you are using width and height, only the parent will be scaled.
Check this link >> for more examples https://css-tricks.com/scale-svg/
This is legit. Transform is native SVG functionality and should always work fine with SVG elements.
If you need only one specific size for it to look nicely I suggest you to edit the SVG sprite code (it's XML looking exactly like HTML so you will have no problems understanding it), ensure all SVG elements are encapsuled in one group and add transform as an attribute to this group. This is basically like opening the sprite in a graphic editor, scaling it and saving.
If you have more questions about SVG ask away.

Animate Fill SVG on Hover Mode

Hi guys I am trying to animate the FILL of my SVG.
What I want is that when I hovered my mouse the FILL will come out from the bottom to top filling in the whole circle. But I am stack how to apply the same using CSS3 transfrom: scale property.
As an example check out this demo: http://tympanus.net/Tutorials/CircleHoverEffects/
That example is CSS not SVG I need to apply this pop-up FILL effect on my SVG.
here's my code so far:
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="200px"
height="200px" viewBox="0 0 200 200" style="enable-background:new 0 0 200 200;" xml:space="preserve" id="icon">
<style type="text/css">
.st0
{
fill:none;
stroke:#F2F2F2;
stroke-width:4;
stroke-miterlimit:10;
}
#icon .st0{
-webkit-transition: .5s;
}
#icon:hover .st0{
fill: #ffffff;
stroke: #1f8a4c;
cursor: pointer;
}
</style>
<g id="container">
<circle class="st0" cx="101" cy="99" r="89.333"/>
</g>
<g id="icon-details">
<path class="st0" d="M146.899,134.202c3.856,4.702,2.772,11.963-2.418,16.218l0,0c-5.192,4.258-12.523,3.896-16.38-0.806
l-30.004-36.594c-3.855-4.701-2.772-11.964,2.418-16.22l0,0c5.19-4.256,12.523-3.895,16.377,0.808L146.899,134.202z"/>
<circle class="st0" cx="77.843" cy="72.434" r="33.331"/>
<circle class="st0" cx="77.844" cy="72.434" r="22.343"/>
</g>
</svg>
Check out JSFIDDLE: http://jsfiddle.net/uhkwLuph/2/
I came up with an interesting but working solution. We want to use scale, but out initial fill size should be 0 (scaling a 0-size element does nothing).
However, we know that a pixel is a pixel, and so a circle with as size of, let's say, 0.1 pixels will not render. Thus, we set the initial "fill" circle size to be small, then scale by a large factor:
<g id="fill-group" transform="translate(101, 99)">
<circle class="fill" r="0.1" />
</g>
Also note here that we use a transform property on the group instead of setting cx and cy like on the other elements so that the circle scales with the correct origin.
Then the CSS would look like:
#icon .fill {
-webkit-transition: .5s;
fill: #ffffff;
}
#icon:hover .fill {
-webkit-transform: scale(893, 893);
}
And here's a Fiddle to show it: http://jsfiddle.net/uhkwLuph/20/