Spin animation initiated on hover but still completes when off hover - css

So I have completed some simple code to spin the inside element when you hover on the container.
This works just as I want it when the mouse is hovering over the container but when the mouse is no longer within the container the spin stops.
How can I complete a full spin rotation, initiated by a mouse hover where it will complete a full spin even if the mouse leaves the container, preferably with just CSS.
Current code:
HTML
#keyframes spin {
0% { transform: rotate(0deg); }
25% { transform: rotate(-90deg); }
50%{ transform: rotate(-180deg); }
75% { transform: rotate(-270deg); }
100% { transform: rotate(-360deg); }
}
.logo:hover > .spin{
animation: spin 450ms;
}
.logo{
background: #eee;
width: 100px;
height: 100px;
text-align: center;
line-height: 110px;
}
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet"/>
<a href="#">
<div class="logo">
<i class="fa fa-globe fa-2x spin" aria-hidden="true"></i>
</div>
</a>

This should work ! :)
jQuery(document).ready(function(){
jQuery(".logo").hover(function(){
var logo = jQuery(this);
if(!logo.hasClass('hover')){
logo.addClass('hover');
setTimeout(function(){
logo.removeClass('hover');
}, 450);
}
}, function(){});
});
#keyframes spin {
0% { transform: rotate(0deg); }
25% { transform: rotate(-90deg); }
50%{ transform: rotate(-180deg); }
75% { transform: rotate(-270deg); }
100% { transform: rotate(-360deg); }
}
.logo.hover > .spin{
animation: spin 450ms;
}
.logo{
background: #eee;
width: 100px;
height: 100px;
text-align: center;
li
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet"/>
<a href="#">
<div class="logo">
<i class="fa fa-globe fa-2x spin" aria-hidden="true"></i>
</div>
</a>

Related

Standard keyframes in react js doesn't work

Just a simple question about keyframes in css and react js. Have 2 types of animations, first one works but second one no
The second example doesn't work even in global css file and in module.css too
The first example:
import React from "react";
const Home = () => {
return (
<div className="section" style={{ background: "transparent" }}>
<h1>HOME</h1>
</div>
);
};
CSS:
.section{
height: 100vh;
width: 100%;
animation-name: delay;
animation-duration: 2s;
z-index: -1;
}
#keyframes delay {
0%{transform: translateY(30px)}
100%{transform: translateY(0)}
}
Second example:
function Wings() {
return (
<div className='wings'>
<div className='rightWing' >
<img src={rightWing} alt="" />
</div>
<div className='leftWing'>
<img src={leftWing} alt="" />
</div>
</div>
);
}
CSS:
.wings{
z-index: 10;
display: flex;
justify-content: center;
align-items: center;
}
.leftWing{
position: absolute;
transform-origin: 85% 5%;
transform: translateX(25%) rotate(90deg);
animation-name: left-wing;
animation-duration: 2sec;
}
.rightWing{
position: absolute;
transform-origin: 15% 5%;
transform: translateX(-25%) rotate(-90deg);
animation-name: right-wing;
animation-duration: 2sec;
}
#keyframes left-wing {
0%{transform: translateX(25%) rotate(90deg);}
50%{transform: rotate(0deg);}
100%{transform: translateX(25%) rotate(90deg);}
}
#keyframes right-wing {
0%{transform: translateX(-25%) rotate(-90deg);}
50%{transform: rotate(0deg);}
100%{transform: translateX(-25%) rotate(-90deg);}
}
So the question is - Why it doesn't work ? :D
UPD: GUYS ! Always set 2s 3s etc NOT 2SEC :D

why is my css animation not staying in the same place?

When my page is loading, the logo animation starts in the bottom right corner of the screen, even though my logo element is positioned absolute. I really don't understand why this is happening and what to do about it.
Here's my code:
HTML:
<div class="intro position-relative">
<header class="company-name border border-5 p-2 p-sm-4 position-absolute start-50 translate-middle">
<h1 class="lh-1">BAKKES</h1>
<h2 class="lh-1">herenkappers en baardkwekers</h2>
</header>
</div>
CSS:
.company-name {
top: 45%;
animation: fade-names 1s linear forwards;
animation-delay: 0.5s;
opacity: 0;
}
#keyframes fade-names {
from {
opacity: 0;
transform: scale(0.95);
}
to {
opacity: 1;
transform: scale(1);
}
}
Here's a link so you can see what happens: https://amazing-austin-69ee4a.netlify.app/
You can do these codes.
I looked at your website.
.intro .company-name {
top:45%; // remove this
}
.start-50 {
left: 50% !important; // remove this
}
.translate-middle {
-webkit-transform: translate(-50%, -50%) !important; // remove this
transform: translate(-50%, -50%) !important; // remove this
}
.intro {
display: flex; // add this
justify-content: center; // add this
align-items: center; // add this
}

css animation transform - keep arbitrary rotation

I have a CSS animation, for example, like this:
#keyframes my-animation {
0% { opacity: 0; visibility: visible; transform: scale(0,0); }
50% { transform: scale(1.15, 1.15); }
100% { transform: none; }
}
And I want to apply it to a DIV that has an arbitrary rotation e.g. like this:
<div style="width:100px; height:100px; transform: rotate(45deg)"/>
When I apply the CSS animation, keyframes have another transform attribute that only sets scale. As a result, my DIV is rotated back to 0 during the animation and, at the end, it is restored back to 45 degree rotation.
But I want it to keep its arbitrary original rotation. So the question is: is there a way to specify in transform property of the keyframes that it should keep existing (arbitrary) rotation?
Something like transform: scale(1.15, 1.15) rotate(keep) ?
Use CSS variables
.x {
transform: rotate(var(--r,0deg));
height: 50px;
width: 50px;
display:inline-block;
background: green;
animation: my-animation 5s;
margin: 20px;
}
#keyframes my-animation {
0% {
opacity: 0;
transform: scale(0) rotate(var(--r,0deg));
}
50% {
transform: scale(1.15) rotate(var(--r,0deg));
}
}
<div class="x" style="--r:80deg"></div>
<div class="x" ></div>
<div class="x" style="--r:60deg"></div>
Or like below so you can append any transformation to the one defined in the keyframes
:root {
--r: rotate(0deg); /* Use any null transform (ex: translate(0), skew(0deg), etc)*/
}
.x {
transform: var(--r);
height: 50px;
width: 50px;
display:inline-block;
background: green;
animation: my-animation 5s;
margin: 20px;
}
#keyframes my-animation {
0% {
opacity: 0;
transform: scale(0) var(--r);
}
50% {
transform: scale(1.15) var(--r);
}
}
<div class="x" style="--r:rotate(80deg) skew(20deg)"></div>
<div class="x" ></div>
<div class="x" style="--r:rotate(60deg) translate(20px,20px)"></div>
Here's a simple solution without variables - I would just wrap your div and do the scaling on the wrapper, keeping the inner div rotated arbitrarily. Trivial, but does the trick I think.
.box {
height: 50px;
width: 50px;
background: green;
margin: 50px;
}
.scale-me {
animation: my-animation;
animation-duration: 10s;
}
#keyframes my-animation {
0% {
opacity: 0;
transform: scale(0);
}
50% {
transform: scale(1.15);
}
}
<div class="scale-me">
<div class="box" style="transform: rotate(45deg)"></div>
<div class="box" style="transform: rotate(60deg)"></div>
<div class="box" style="transform: rotate(120deg)"></div>
</div>

Animate between fontawesome icons not working in IE

I've created an animation to cycle through a set of individual FontAwesome icons. It is working on latest Firefox and Chrome, but on IE (10, 11, Edge) the icon simply doesn't change.
To prove that IE is at least trying to animate, I've added the colour CSS.
Is this something that just can't be done on IE with CSS alone?
i::before {
animation: battery 5s infinite;
font-size:2em;
}
#keyframes battery {
0% { content: "\f244"; color:red; }
25% { content: "\f243"; color:green; }
50% { content: "\f242"; color:blue; }
75% { content: "\f241"; color:yellow; }
100% { content: "\f240"; color:purple; }
}
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.6.3/css/all.css" crossorigin="anonymous">
<i class="fas fa-battery-empty"></i>
As I commented, you can try with stacking icons:
i.fas {
animation: battery 5s infinite;
opacity:0;
color:red;
}
i.fas:nth-child(2) {animation-delay:1s;}
i.fas:nth-child(3) {animation-delay:2s;}
i.fas:nth-child(4) {animation-delay:3s;}
i.fas:nth-child(5) {animation-delay:4s;}
#keyframes battery{
0%,20% { /* 20 = 100 / 5 */
opacity:1;
}
21%,100% {
opacity:0;
}
}
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.6.3/css/all.css" crossorigin="anonymous">
<span class="fa-stack fa-4x">
<i class="fas fa-stack-1x fa-battery-empty"></i>
<i class="fas fa-stack-1x fa-battery-quarter"></i>
<i class="fas fa-stack-1x fa-battery-half"></i>
<i class="fas fa-stack-1x fa-battery-three-quarters"></i>
<i class="fas fa-stack-1x fa-battery-full"></i>
</span>
For IE, you may look instead at text-indent and move the icon steps by steps instead updating the content value.
i::after {
animation: battery 10s infinite;
display: inline-block;
width: 0;
text-indent: -1.25em;
content: " \f244 \f243 \f242 \f241 \f240";
white-space: nowrap;
position:relative;
z-index:-1;
}
i {
overflow: hidden;
font-size: 2em;
}
#keyframes battery {/* update values and steps to your needs */
0% {
text-indent: -1.25em;
color: green;
}
19.9999% {
text-indent: -1.25em;
}
20% {
text-indent: -2.75em;
color: green;
}
39.999% {
text-indent: -2.75em;
}
40% {
text-indent: -4em;
}
59.999% {
text-indent: -4em;
color: blue;
}
60% {
text-indent: -5.25em;
}
79.999% {
text-indent:-5.25em;
color: orange;
}
80% , 100%{
text-indent: -6.5em;
color: red;
}
}
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.6.3/css/all.css" crossorigin="anonymous">
<i class="fas fa-battery-empty"></i>
If you're using the SVG sprites with the JS version of font-awesome then the CSS is slightly different.
The font-awesome JS removes the fas class and turns it into a data-prefix property so you'll have to add an identifier to the <span>
.battery svg {
animation: battery 5s infinite;
opacity: 0;
color: red;
}
.battery svg:nth-child(2) {
animation-delay: 1s;
}
.battery svg:nth-child(3) {
animation-delay: 2s;
}
.battery svg:nth-child(4) {
animation-delay: 3s;
}
.battery svg:nth-child(5) {
animation-delay: 4s;
}
#keyframes battery {
0%, 20% { /* 20 = 100 / 5 */
opacity: 1;
}
21%, 100% {
opacity: 0;
}
}
...
<script src="https://pro.fontawesome.com/releases/v5.13.0/js/all.js" crossorigin="anonymous"></script>
<span class="fa-stack fa-4x battery">
<i class="fas fa-stack-1x fa-battery-empty"></i>
<i class="fas fa-stack-1x fa-battery-quarter"></i>
<i class="fas fa-stack-1x fa-battery-half"></i>
<i class="fas fa-stack-1x fa-battery-three-quarters"></i>
<i class="fas fa-stack-1x fa-battery-full"></i>
</span>

How does rotation combined with translation work inside CSS animation?

I saw this animation on codepen, and I don't know why it's written this way to have this effect, but I think it's going to have the effect of rotating 360deg clockwise, 360deg counterclockwise, instead of bouncing up and down or left and right
I'm particularly puzzled with these Keyframe animation
#keyframes move{
from {
transform: rotate(360deg) translateX(1.125em) rotate(-360deg);
}
to {
transform: rotate(-360deg) translateX(1.125em) rotate(360deg);
}
}
Results the following
https://i.stack.imgur.com/9oWnw.gif
From the specification we can see how the broswer should deal with interpolation between transform values. In this case we use this:
If from- and to-transform have the same number of transform functions,
each transform function pair has either the same name, or is a
derivative of the same primitive: Interpolate each transform function
pair as described in Interpolation of transform functions. The
computed value is the resulting transform function list.
So the browser will change the first rotate from 360deg to -360deg and the same for the last rotate while translateX will kept the same. We will then have the following steps:
transform: rotate(360deg) translateX(1.125em) rotate(-360deg);
transform: rotate(350deg) translateX(1.125em) rotate(-350deg);
transform: rotate(340deg) translateX(1.125em) rotate(-340deg);
....
transform: rotate(0) translateX(1.125em) rotate(0);
....
....
transform: rotate(-360deg) translateX(1.125em) rotate(360deg);
Now we need to understand how rotate(-adeg) translateX(b) rotate(adeg) works. First you may notice that the rotation won't have any visual effect on the element since we deal with a circle, it will simply affect how the translation will work and more precisely it's the first rotation that is important (the one in the left).
.container {
width: 50px;
height: 50px;
margin: 50px;
border:2px solid;
}
.box {
width: 50px;
height: 50px;
background: red;
border-radius: 50%;
animation: move 2s linear infinite;
}
.alt {
animation: move-alt 2s linear infinite;
}
#keyframes move {
from {
transform: rotate(360deg) translateX(1.125em) rotate(-360deg);
}
to {
transform: rotate(-360deg) translateX(1.125em) rotate(360deg);
}
}
#keyframes move-alt {
from {
transform: rotate(360deg) translateX(1.125em);
}
to {
transform: rotate(-360deg) translateX(1.125em);
}
}
<div class="container">
<div class="box">
</div>
</div>
<div class="container">
<div class="box alt">
</div>
</div>
As you can see both animation are equivalent visually.
Now the effect is as follow: each time we rotate the X-axis and then we translate our element consider the new rotated axis. It's like we rotate the coordinate system then we translate OR its like we do the translation once (since it's the same) then we keep rotating the coordinate system thus we have a rotation at the end.
Now if we consider the opposite transform nothing will happen visually:
.container {
width: 50px;
height: 50px;
margin: 50px;
border: 2px solid;
}
.box {
width: 50px;
height: 50px;
background: red;
border-radius: 50%;
animation: move 2s linear infinite;
}
#keyframes move {
from {
transform: translateX(1.125em) rotate(-360deg);
}
to {
transform: translateX(1.125em) rotate(360deg);
}
}
<div class="container">
<div class="box">
</div>
</div>
In this case we translate the coordinate system by the same translation then we rotate our circle. If we change it to a square we will see the effect
.container {
width: 50px;
height: 50px;
margin: 50px;
border: 2px solid;
}
.box {
width: 50px;
height: 50px;
background: red;
animation: move 2s linear infinite;
}
#keyframes move {
from {
transform: translateX(1.125em) rotate(-360deg);
}
to {
transform: translateX(1.125em) rotate(360deg);
}
}
<div class="container">
<div class="box">
</div>
</div>
And here is how your initial animation will look with a square:
.container {
width: 50px;
height: 50px;
margin: 50px;
border: 2px solid;
}
.box {
width: 50px;
height: 50px;
background: red;
animation: move 2s linear infinite;
}
#keyframes move {
from {
transform:rotate(360deg) translateX(1.125em) rotate(-360deg);
}
to {
transform:rotate(-360deg) translateX(1.125em) rotate(360deg);
}
}
<div class="container">
<div class="box">
</div>
</div>
We rotate the coordinate system, we translate our element then we rotate the element so it's like we rotate our the element inside a bigger one that is also rotating in the opposite direction.
If you change the timing function to something else than linear you will have the same rotation but it won't be linear, it will be slower/faster in some interval:
.container {
width: 50px;
height: 50px;
margin: 50px;
border: 2px solid;
}
.box {
width: 50px;
height: 50px;
background: red;
animation: move 2s ease-in-out infinite;
}
#keyframes move {
from {
transform:rotate(360deg) translateX(1.125em) rotate(-360deg);
}
to {
transform:rotate(-360deg) translateX(1.125em) rotate(360deg);
}
}
<div class="container">
<div class="box">
</div>
</div>
This is a simplified explanation, you may check this answer if you want more details about how we deal with multiple function inside transform and how the order is important: Simulating transform-origin using translate

Resources