How to disable an animation when opening or refereshing the page - css

I have made a little animation that add a line under the box from the left to the right when it's hovered and the line go back from the left to the right when the mouse isn't hovering the box, but the issue is that the line goes back from the left to the right when I refresh the page. Is there a solution to disable the animation when I open the page or when I refresh it (if possible without JavaScript)
body {
background-color: black;
}
.box {
width: 100px;
height: 100px;
margin: 40px auto;
background-color: #f44336;
position: relative;
}
.box::after {
content: '';
position: absolute;
bottom: -7px;
width: 100%;
height: 3px;
background-color: #fff;
animation: out 400ms linear forwards;
transform-origin: right center;
}
.box:hover::after {
animation: in 400ms linear;
transform-origin: left center;
}
#keyframes in {
from {
transform: scaleX(0);
}
to {
transform: scaleX(1);
}
}
#keyframes out {
from {
transform: scaleX(1);
}
to {
transform: scaleX(0);
}
}
<div class="box"></div>

I changed your animation to a transition instead. Is this what you're after?
body {
background-color: black;
}
.box {
width: 100px;
height: 100px;
margin: 40px auto;
background-color: #f44336;
position: relative;
}
.box::after {
content: '';
position: absolute;
bottom: -7px;
width: 100%;
height: 3px;
background-color: #fff;
transform: scaleX(0);
transform-origin: right center;
transition: transform 400ms linear;
}
.box:hover::after {
transform: scaleX(1);
transform-origin: left center;
}
<div class="box"></div>

I don't believe this is possible using only css - you can use a css declaration when a mouse-over ends, however it will always trigger upon load.
You can however use simple JS using classes "on" and "off" to differentiate 'page load' and 'hover off'.
The code in this instance would be:
demo
$(".box").hover(
function () {
$(this).removeClass('off').addClass('on');
},
function () {
$(this).removeClass('on').addClass('off');
}
);
body {
background-color: black;
}
.box {
width: 200px;
height: 200px;
margin: 40px auto;
background-color: #f44336;
position: relative;
}
.box::after {
content: '';
position: absolute;
bottom: -7px;
height: 3px;
background-color: #fff;
}
.box.off::after {
width: 100%;
animation: out 400ms linear forwards;
transform-origin: right center;
}
.box.on::after {
width: 100%;
animation: in 400ms linear;
transform-origin: left center;
}
#keyframes in {
from {
transform: scaleX(0);
}
to {
transform: scaleX(1);
}
}
#keyframes out {
from {
transform: scaleX(1);
}
to {
transform: scaleX(0);
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="box"></div>

Related

CSS animations with transform: translate

Please help, when I'm trying to play animation with moving ball in position X and Y at the same time it doesn't work, some strange behaviour. I would like to look like a batted and falling ball
.ball {
position: absolute;
left: 18%;
bottom: 100px;
width: 40px;
height: 40px;
background-color: cadetblue;
border-radius: 50%;
animation: fly-ball-x 2s, fly-ball-y 2s;
}
#keyframes fly-ball-x {
100% {
transform: translateX(300px);
}
}
#keyframes fly-ball-y {
100% {
transform: translateY(100px);
}
}
<div class="ball"></div>
**The result I'm expecting is like the code below:**
#keyframes fly-ball-x {
100% {
left: 300px;
}
}
#keyframes fly-ball-y {
100% {
bottom: 0;
}
}
.ball {
position: absolute;
left: 18%;
bottom: 100px;
width: 40px;
height: 40px;
background-color: cadetblue;
border-radius: 50%;
animation: fly-ball-x 2s cubic-bezier(0.17, 0.67, 0.6, 1), fly-
ball-y 2s;
}
<div class="ball"></div>
.ball {
position: absolute;
left: 18%;
bottom: 100px;
width: 40px;
height: 40px;
background-color: cadetblue;
border-radius: 50%;
animation: fly-ball 2s
}
#keyframes fly-ball {
100% {
transform: translateX(300px) translateY(100px);
}
}
<div class="ball"></div>
It is because you weren't running the animations concurrently. Here both translations are just being run at the same time. You just had a bit more than you needed.
EDIT
Check out this blog post. It gives explanations on the kinds of curves it seems you are going for Curved Path Animations In CSS

Creating a gravity-like effect in CSS falling animation and calculating change of radius of a 'circle' when using rotateX

I have the following animation of a ball falling down and bouncing back up:
body {
margin: 0;
padding: 0;
}
.ball {
width: 20px;
height: 20px;
margin: 0 auto;
border-radius: 50%;
background-color: black;
animation: bounce 2s infinite linear;
}
.ground {
display: block;
width: 100%;
border-bottom: 1px solid black;
position: absolute;
top: 100px;
}
#keyframes bounce {
0%,100% {
transform: translateY(0);
}
20% {
background-color: black;
transform: translateY(40px);
}
50% {
background-color: red;
transform: translateY(84px) rotateX(45deg);
}
70% {
background-color: black;
transform: translateY(40px);
}
}
<div class = "ball">
</div>
<div class = "ground">
</div>
As you can see, I tried to make the ball have a "squeezed" effect when it touches the ground. I had to use the translateX to 84px to maintain the touching of the ball with the ground. I got that 84px by trial and error. Is there a formula which I can use to calculate the offset (i.e. 4px in this case)?
The ball is falling at a linear speed, I've tried using ease-in and ease and it didn't work. I've also tried different numbers from cubic-bezier.com. How do I make it so that the velocity increases along with time because of gravitational acceleration and deceleration when it is bouncing back up?
Check solution below if you hate maths 1
Since you are rotating the element 45deg you are having something like this:
What you are looking for is the Green line which you can get with the following formula:
width/2 - X
Where
X = Width/2*cos(45deg)
so you will have Width/2*(1 - cos(45deg)) ~ Width/2*(1 - 0.707)
You can then adjust the percentage value to control velocity. As a side note, you should not get to initial value but a lower value to have a more realistic animation:
body {
margin: 0;
padding: 0;
}
.ball {
width: 20px;
height: 20px;
margin: 0 auto;
border-radius: 50%;
background-color: black;
animation: bounce 2s infinite ease-in;
}
.ground {
display: block;
width: 100%;
border-bottom: 1px solid black;
position: absolute;
top: 100px;
}
#keyframes bounce {
0% {
transform: translateY(0);
}
30% {
background-color: black;
transform: translateY(80px);
}
40% {
background-color: red;
transform: translateY(calc(80px + 10px*(1 - 0.707))) rotateX(45deg);
}
50% {
background-color: black;
transform: translateY(80px);
}
100% {
background-color: black;
transform: translateY(50px);
}
}
<div class = "ball">
</div>
<div class = "ground">
</div>
1 You can also avoid the calculation by simply changing the transform-origin to rotate from the bottom thus the space will be reduced from the top:
body {
margin: 0;
padding: 0;
}
.ball {
width: 20px;
height: 20px;
margin: 0 auto;
border-radius: 50%;
background-color: black;
animation: bounce 2s infinite linear;
transform-origin:bottom;
}
.ground {
display: block;
width: 100%;
border-bottom: 1px solid black;
position: absolute;
top: 100px;
}
#keyframes bounce {
0% {
transform: translateY(0);
}
30% {
background-color: black;
transform: translateY(78px);
}
40% {
background-color: red;
transform: translateY(80px) rotateX(45deg);
}
50% {
background-color: black;
transform: translateY(78px);
}
100% {
background-color: black;
transform: translateY(50px);
}
}
<div class = "ball">
</div>
<div class = "ground">
</div>
If you want to have a non-realistic bounce effect you can try this:
body {
margin: 0;
padding: 0;
}
.ball {
width: 20px;
height: 20px;
margin: 0 auto;
border-radius: 50%;
background-color: black;
animation: bounce 2s infinite linear;
transform-origin:bottom;
}
.ground {
display: block;
width: 100%;
border-bottom: 1px solid black;
position: absolute;
top: 100px;
}
#keyframes bounce {
0%,100% {
transform: translateY(0);
}
35%,65% {
background-color: black;
transform: translateY(40px);
}
45%,55% {
background-color: black;
transform: translateY(75px);
}
50% {
background-color: red;
transform: translateY(80px) rotateX(45deg);
}
}
<div class = "ball">
</div>
<div class = "ground">
</div>

How to scale (transform) div in width and height without scaling border width?

#keyframes scale {
0% {
transform: scale(0);
}
100% {
transform: scale(5);
}
}
div#scale {
width: 10px;
height: 10px;
border: 1px solid;
border-radius: 50%;
animation: scale 5s infinite;
}
<div id="scale"></div>
How to scale (transform) div in width and height without scaling border width? I'm trying to build this effect.
As for the workaround / alternative you can just animate its width and height:
body {padding:50px}
#scale {
border: 1px solid;
border-radius: 50%;
animation: scale 3s linear infinite;
position: relative;
top: 0;
left: 0;
}
#keyframes scale {
0% {
width: 0;
height: 0;
}
100% {
width: 50px;
height: 50px;
top: -25px;
left: -25px;
}
}
<div id="scale"></div>
To make it grow from the center use negative margins / values for the top and left properties equal to half of the change in size, so in this case that's -25px.
One option you have is to use synced elements. One that scales and another one, empty, that changes size while keeping border-width. The other element I used is the ::after of a wrapper.
#keyframes scale-div {
0% {
transform: scale(0);
}
50% {
transform: scale(1)
}
100% {
transform: scale(0);
}
}
#keyframes scale-border {
0% {
width: 0px;
height: 0px;
}
50% {
width: 100px;
height: 100px;
}
100% {
width: 0px;
height: 0px;
}
}
.scale {
animation: scale-div 5s steps(300, end) infinite ;
transition-timing-function: cubic-bezier(.4,0,.2,1);
background-color: rgba(0,0,0,.05);
border-radius: 50%;
}
.scale,.scale-wrapper {
width: 100px;
height: 100px;
}
.scale-wrapper {
position: relative;
}
.scale-wrapper::after {
position: absolute;
border-radius: 50%;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
border: 1px solid black;
width: 98px;
height: 98px;
animation: scale-border 5s steps(300, end) infinite;
transition-timing-function: cubic-bezier(.4,0,.2,1);
content: '';
}
<div class="scale-wrapper">
<div class="scale"></div>
</div>
There are ton of problems with scaling transforms since it's ratio based. if you scale it, it's going to scale its layout, border even :after, :before elements and all children.
For what you're trying to do it's best if you just use svg. Svg circle element's radius property can be animated. I suggest you run browser support test on it; However, svg support is pretty wide especially with animations.
svg .circle {
cx: 50%;
cy: 50%;
r: 20px;
stroke: #dfdfdf;
stroke-width: 2px;
transform: translateZ(0);
fill: none;
animation: ping 2s infinite;
}
#keyframes ping {
from {
r: 10px;
}
to {
r: 40px;
}
}
<svg><circle r="20px" class="circle"/></svg>
#keyframes scale {
0% {
transform: scale(0); border: 1px solid;
}
100% {
transform: scale(5); border: 5px solid;
}
}
div#scale {
width: 10px;
height: 10px;
border-radius: 50%;
animation: scale 5s infinite;
}
did you try above code ?

Delay between CSS Animation with 0.1s duration

i have a little issue with the css animation and keyframe feature...
i have a little monster with blinking eyes... the eyes should blink just 0.1s
And then i want to have a duration... and then the animation should loop.
This is my animation/keyframe:
#keyframes blinkingEyes {
0% {
transform: rotateX(0deg);
}
36% {
transform: rotateX(90deg);
}
100% {
transform: rotateX(90deg);
}
}
And this is my animation property:
animation: blinkingEyes 0.15s 1s infinite linear;
JSFIDDLE
I found a workaround with a x% between my start and end value. But nothing works for me.. i hope you could help me
You need several keyframes for this, and then make the animation run infinite times.
See:
#monster {
margin-top: 60px;
height: 93px;
width: 75px;
border-radius: 120px;
background: yellow;
/* text-align: center; */
position: relative;
}
.eye {
height: 12px;
width: 8px;
background: black;
border-radius: 10px;
margin-top: 30px;
float: left;
animation: blinkingEyes 1.5s linear infinite;
}
.eyeLeft {
margin-left: 18px;
}
.eyeRight {
margin-left: 22px;
}
.mouth {
font-weight: 900;
transform-origin: 50% 50%;
/* display: inline-block; */
width: 5px;
margin: 0 auto;
height: 20px;
/* text-align: center; */
/* left: 47%; */
position: absolute;
top: 47px;
transform: rotate(90deg);
left: 35px;
}
#keyframes blinkingEyes {
0%, 97%, 100% {
transform: rotateX(0deg);
}
98%, 99% {
transform: rotateX(90deg);
}
}
<div id="monster">
<div class="monsterBody">
<div class="eye eyeLeft">
</div>
<div class="eye eyeRight">
</div>
<div class="mouth">
)
</div>
</div>
</div>

CSS3 transform: translateX equivalent for right

I want to do this: -webkit-transform: translateX(300px) but from the right instead of having the origin on left.
I tried -webkit-transform-origin: 100% 100% and even top right and it didn't affect it.
Is there a way to do it?
By the power of CSS:
body {
padding: 0;
margin: 0;
}
#page {
position: absolute;
width: 100%;
height: 100%;
background-color: black;
z-index:2;
right:0;
}
#left_drawer {
background-color: #222222;
position: absolute;
top: 0;
right: 0;
width: 300px;
height: 100%;
z-index: 1;
}
#toggle {
width: 50px;
height: 50px;
background-color: red;
float: right;
}
.open_drawer {
-webkit-animation: open_drawer 300ms ease-in-out;
-webkit-animation-fill-mode: forwards;
-webkit-transform: translateX(0);
}
#-webkit-keyframes open_drawer {
to {
-webkit-transform: translateX(-300px);
}
}
This will make it slide in from the right. Fiddle.

Resources