I have two animations: on element load and hover:
div {
animation: slide-up 2s;
-webkit-animation: slide-up 2s;
-moz-animation: slide-up 2s;
}
div:hover{
animation: rotate 2s;
-webkit-animation: rotate 2s;
-moz-animation: rotate 2s;
}
The slide-up animation runs once the element is loaded, and rotate runs when element is hovered. However, now the element slides up on mouse leave and I don't know how to prevent this. So I'd like to turn off slide-up animation on hover.
The rotate animation uses transform property, and slide-up just changes margins.
Reason:
The slide-up animation executes once again when you move the mouse out of the element because of the following reasons:
On load, the element has only one animation (which is slide-up). The browser executes this.
On hover, the animation property again specifies only one animation (which is rotate). This makes the browser remove the slide-up animation from the element. Removing the animation makes the browser also forget about the execution state or the execution count of it.
On hover out, the default div selector becomes applicable for the element and so the browser again removes the rotate animation and attaches the slide-up animation. Since it is being re-attached, the browser thinks it must execute it again.
Solution:
You can make the slide-up animation run only once by making sure that the animation is actually never removed from the element even when :hover is on and animation-iteration-count is 1.
In the below snippet, you'd note how I have retained the slide-up animation definition within :hover selector also. This makes the browser see this animation as ever present and since this animation is already executed once on load, it won't execute it again (because of iteration count).
(Note: Just to avoid any confusions - the default value for animation-iteration-count is 1 but I had made it explicit for the purpose of explanation. It is not the primary reason but is just an extra step to make sure that its value doesn't mess up the solution.)
div {
height: 100px;
width: 100px;
border: 1px solid;
animation: slide-up 2s 1;
}
div:hover {
animation: slide-up 2s 1, rotate 2s forwards;
}
#keyframes slide-up {
from {
margin-top: 100px;
}
to {
margin-top: 0px;
}
}
#keyframes rotate {
from {
transform: rotate(0deg);
}
to {
transform: rotate(60deg);
}
<div>Some div</div>
just add an animation-play-state: paused;
div:hover{
animation: rotate 2s, slide-up paused;
-webkit-animation: rotate 2s, slide-up paused;
-moz-animation: rotate 2s, slide-up paused;
}
Just add another animation after a comma. For example, if I want to create a box that will fade in(1st animation) and then its shadow size keeps on changing(2nd animation), then this is the CSS that I am gonna use:
#box{
width: 300px;
height: 250px;
border: 2px solid white;
border-radius: 20px;
display: block;
margin-left: 500px;
margin-top: 190px;
background-color: rgb(0, 204, 228);
animation: animate1 3s 1, animate2 1s infinite;
text-align: center;}
#keyframes animate1{
0% {
opacity: 0;
}
100%{
opacity: 1;
}
}
#keyframes animate2{
0%{box-shadow: 0px 0px 10px 0px gray; }
50%{box-shadow: 0px 0px 30px 0px gray; }
100%{box-shadow: 0px 0px 10px 0px gray; }}
Related
I have been trying to figure this out for some time now, no success so far though: I want to run a typing animation using CSS. The animation has to start after 7 seconds. I can't figure out how to do this tho. My code looks like this:
HTML
<div class='background-fullwidth'>
<div class="css-typing">
This text will pop up using an typewriting effect
</div>
</div>
CSS
.css-typing {
width: 360px;
white-space: nowrap;
overflow: hidden;
-webkit-animation: type 3s steps(50, end);
animation: type 3s steps(55, end);
-o-animation: type 5s steps(50, end);
-moz-animation: type 3s steps(55, end);
padding: 10px;
}
.background-fullwidth {
width: 400px;
background-color: rgba(0, 50, 92, 0.7);
}
#keyframes type {
from { width: 0; }
to { width: 360px; }
}
#-moz-keyframes type {
from { width: 0; }
to { width: 360px; }
}
#-webkit-keyframes type {
from { width: 0; }
to { width: 360px; }
}
Does anyone know how to add this timer - let's say the animation has to start after 7 seconds? From second 1 to 7 only the wraping DIV (blue background) has to be shown.
Fiddle looks like this:
CSS Animation
You'll have to use 3 different animation properties.
animation-delay: It helps you achieve the solution to the basic problem of starting the animation after 7 seconds.
animation-iteration-count; This property lets you decide the number of times the animation repeats itself. Setting it to 1 will limit it to a single animation instance.
animation-fill-mode: Setting this property to forward will make sure that the width remains 320 at the end of the animation.
CSS
animation-delay: 2s;
animation-iteration-count: 1;
animation-fill-mode: forwards;
width: 0; // So that the animation starts from 0
Review the fiddle at https://jsfiddle.net/kaminasw/at6mbxyr/
By experimenting for several times i found an easy/clever way to make this possible :
You can start the animation after certain time
Element will be hidden until the start of the animation.
My Keyframe Animation (It can be any animation) :
#keyframes fadeUp{
from{
transform: translateY(100px);
opacity: 0;
}
to{
opacity: 1;
}
}
Then i used the animation like:
h1{
animation: fadeUp 1.5s ease 7s backwards; /*Waiting time of 7 seconds*/
}
Above code is similar to :
h1{
animation-name: fadeUp;
animation-duration: 1.5s;
animation-timing-function: ease;
animation-delay: 7s; /*For X waiting time change the value to Xs*/
animation-fill-mode: backwards;
}
:-)
You need to use animation-delay for that like this:
.css-typing {
--other properties--
-webkit-animation-delay: 7s; /* Safari 4.0 - 8.0 */
animation-delay: 7s;
}
Use animation-delay property:
animation-delay: 2s;
-webkit-animation-delay: 2s;
there is a property animation-delay
provide this property to your class element.
check the below example animation starts after 7 seconds
http://codepen.io/anon/pen/dNqmvB
[Edit: Solution was to create two containers, with the second animation container set to left: 100%.]
I have a very basic animation to move a large gif across the page, the gif is 1536px wide.
The page can be infinitely wide and thus the animation starts at right:0px and ends at right:100%. In reality, I don't expect the page to ever be larger than the highest monitor resolutions used currently.
In order to create the feeling that the animation was occurring infinitely I have created a second animation and started this at right:-1536px and ending at right:100%.
Unfortunately, as this second animation is covering a greater distance it is moving faster than the first and my attempted seamless animation doesn't work. Is there a way to specify that animation-duration work at a constant 1px per second or something equivalent instead of a duration? I don't believe I can increase the duration to match as the browser could be any size.
Any help or ideas appreciated!
My code is as follows:
#-webkit-keyframes frontrocks-anim2 {
0%{right:-1536px;}
100%{right:100%;}
}
#-moz-keyframes frontrocks-anim2 {
0%{right:-1536px;}
100%{right:100%;}
}
.frontrocks-anim2 {
-webkit-animation:frontrocks-anim2 30s infinite;
-webkit-animation-timing-function:linear;
-webkit-animation-delay: 0s;
-moz-animation:frontrocks-anim2 30s infinite;
-moz-animation-timing-function:linear;
-moz-animation-delay: 0s;
}
UPDATE
A better solution is to adapt Oriol's comment from https://stackoverflow.com/a/21088405/603369
That provides a smoothly scrolling background, so all that is left is to animate the background element to "fly in" upon page load.
The problem is that the initial "fly-in" must be based on the width of the container (e.g., the page), while the repeating background must be based on the width of the background image. That leads to some oddities in timing, where the initial "fly-in" from the right side may be significantly faster or slower than the background animation. You might be able to adapt this solution further by using JavaScript to adjust the timing based on the width of the page, but this should give you a starting point.
header {
position: relative;
overflow-x: hidden;
width: 100%;
height: 52px;
border: 1px solid #ccc;
}
.bg {
position: absolute;
left: 0;
top: 0;
bottom: 0;
right: -1536px;
background: url(https://placehold.it/1536x50/cceecc) 0% 0% repeat;
z-index: -1;
-webkit-animation-name: slide-in, bg-anim-repeat;
-webkit-animation-duration: 5s, 5s;
-webkit-animation-timing-function: linear, linear;
-webkit-animation-iteration-count: 1, infinite;
-webkit-animation-delay: 0s, 5s;
}
#-webkit-keyframes bg-anim-repeat {
0% {-webkit-transform: translateX(0);}
100% {-webkit-transform: translateX(-1536px);}
}
#-webkit-keyframes slide-in {
0% {left: 100%;}
100% {left: 0;}
}
<header>
<div class="bg"></div>
</header>
Original
If the page is larger than 1536x2, you're going to have an odd visual look as the two gifs march across the screen. But if this is what you want to go with, try delaying the beginning of the second animation until halfway through the first animation.
Demo of the second option is below
header {
position: relative;
overflow-x: hidden;
width: 100%;
height: 52px;
border: 1px solid #ccc;
}
header img {
position: absolute;
left: 100%;
}
#-webkit-keyframes frontrocks-anim {
0%{left:100%;}
100%{left:-1536px;}
}
#image1, #image2 {
-webkit-animation:frontrocks-anim 10s infinite;
-webkit-animation-timing-function:linear;
-webkit-animation-delay: 0s;
-moz-animation:frontrocks-anim 10s infinite;
-moz-animation-timing-function:linear;
-moz-animation-delay: 0s;
}
/* Delay is 1/2 of the total animation time */
#image2 {
-moz-animation-delay: 5s;
-webkit-animation-delay: 5s;
}
<header>
<img src="https://placehold.it/1536x50/cceecc" alt="moving image 1" id="image1">
<img src="https://placehold.it/1536x50/eecccc" alt="moving image 1" id="image2">
</header>
I'm fading in some buttons with #keyframe animation from opacity: 0 to opacity: 1.
div{
opacity: 1;
animation: fadeIn 1s forwards;
-webkit-animation: fadeIn 1s forwards;
}
#-webkit-keyframes fadeIn {
0%{
opacity: 0;
}100%{
opacity: 1;
}
}
#keyframes fadeIn {
0%{
opacity: 0;
}100%{
opacity: 1;
}
}
div:hover{
opacity: .5 !important; /* THIS DOES NOT HAPPEN BECAUSE THE OPACITY WAS ANIMATED */
color: red;
}
On :hover, I'd like to change the opacity to .5 but it appears that after a property is animated using #keyframe, it can't be changed.
Simple example:
http://jsfiddle.net/Lzcedmuq/3/
PS: In the real web-app, I am also scaling the buttons in so the fix I need is more than just for opacity. I need to be able to change any property that has been animated. I can do it with JS hackery but I don't want to.
Disable the animation as part of the hover state:
div:hover{
opacity: .5;
-webkit-animation: none;
animation: none;
color: red;
}
One issue with this is that the animation will restart when the hover ends.
This fixed the problem
opacity: 0.5 !important;
I can't answer to why the browser doesn't allow changes to animated styles, but it must have a higher priority then any new specified styles... so with that in mind you can use the !important to force that style to take top priority.
Demo
If you look at my code and run it.
#-webkit-keyframes circle {
from { transform:rotate(0deg); }
to { transform:rotate(180deg); }
}
#-webkit-keyframes inner-circle {
from { transform:rotate(0deg); }
to { transform:rotate(-180deg); }
}
#one {
position: absolute;
left: 500px;
top: 200px;
width:100px;
height:100px;
border-radius: 50px;
background-color: #000000;
}
#two {
width:100px;
height:100px;
margin: 0px auto 0;
color:orange;
font-size:100px;
line-height:1;
transform-origin:50% 200px;
}
#one:hover > div {
animation: circle 1s linear infinite;
-webkit-animation: circle 1s linear infinite;
}
#one:hover > div > div {
animation: inner-circle 1s linear infinite;
-webkit-animation: inner-circle 1s linear infinite;
}
</style>
<div id="one">
<div id="two"><div id="three">☻</div></div>
</div>
you will notice that the smile face keeps on looping the animation of rotating 180deg. I don't want this. I only want it to do the animation once every time I hover over the black circle. How do I do this?
If you don't want the animation to occur infinitely, remove infinite from the animation shorthand.
In addition, you will also need to add forwards in order to to prevent the animation from resetting each time. When adding forwards to the animation shorthand, you are essentially changing the property animation-fill-mode from the default value of none to forwards.
From MDN:
The animation-fill-mode CSS property specifies how a CSS animation should apply styles to its target before and after it is executing.
#one:hover > div {
animation: circle 1s linear forwards;
-webkit-animation: circle 1s linear forwards;
}
#one:hover > div > div {
animation: inner-circle 1s linear forwards;
-webkit-animation: inner-circle 1s linear forwards;
}
Change all the infinite values to the amount of times you want the animation to loop. In your case it will be once so you want to change infinite to 1.
I have an element that I have a set of #-webkit-keyframes to animate in. On page load, these keyframes run, and the intro looks great.
Next, I have a second set of #-webkit-keyframes on hover and set to repeat, so on hover, that element has a looping animation. That also works great.
However, the instant I move the mouse away from the element, the first (intro) set of keyframes gets run again. I don't want it to run after it first runs. Is there an easy way to prevent this in CSS?
Minimal example of what I have
#e { -webkit-animation: fadeIn 1s ease-out 0.5s; } /* Fades in on load, BUT gets called when mouse moves away as well */
#e:hover { -webkit-animation: pulse 1s ease-in-out 0s infinite alternate; } /* Works fine, pulses on hover */
Also, can someone with 1500+ reputation edit the tags and add the webkit-animation tag? I can't believe it hasn't been created yet… :\
There is no pure CSS way of accomplishing what you need. You can add the animation to a parent element or to a wrapper and animate each element separately:
.wrapper {
-webkit-animation: fadeIn .5s ease-out 0 1;
}
#e {
width: 100px;
height: 100px;
background-color: #000;
}
#e:hover {
-webkit-animation: pulse 100ms ease-in-out 0s infinite alternate;
}
#-webkit-keyframes fadeIn {
0% { opacity: 0; }
100% { opacity: 0.5;}
}
#-webkit-keyframes pulse {
0% { background-color: #000; }
100% { background-color: #c00; }
}
http://jsfiddle.net/3PuT2/