Webkit Keyframes on Hover - Prevent Previous Animation - html

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/

Related

CSS animation starts after certain amount of time

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

Using two animations on one element, CSS

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; }}

Preserve the last keyframe property in CSS animations

I have a div with some text:
<div>Rain.js</div>
and its CSS:
div {
-webkit-animation: fadein 2s;
color:black;
font-size:70px;
}
I want to make the div fade in so I made an animation fadein to change the opacity of the div from 0 to 0.1
#keyframes fadein {
from { opacity: 0; }
to { opacity: 0.1; }
}
As you can see here the fadein from opacity 0 to 0.1 occurs in 2 seconds as expected. But after 2 seconds the opacity goes from 0.1 to 1.
1) Why does this happen?
2) How can I prevent this from happening?
You have not added animation-fill-mode: forwards to preserve the final state of the animation.
Since there are no default properties set for opacity in your CSS rules and the animation-fill-mode by default is none, the element takes the default opacity value of 1 after the animation is finished.
JSfiddle Demo
div {
animation: fadein 2s;
color: black;
font-size: 70px;
animation-fill-mode: forwards;
}
#keyframes fadein {
from {
opacity: 0;
}
to {
opacity: 0.1;
}
}
<div>Rain.js</div>
When the animation ends it puts the div in his opacity default state, which is not set. (therefore it will be 1).
Add to your CSS on the div:
opacity: 0.1;
Demo: http://jsfiddle.net/qm3f6717/1/
After the fadein is done, the div takes on its specified values.
You simply need to make the opacity of the div equal to the final key frame opacity value.
div
{
-webkit-animation: fadein 2s;
color:black;
font-size:70px;
opacity:0.1;
}

Delay in infinite fade in & out CSS3 animation

I am working on the below:
Fiddle Code
Here is HTML:
<div id="animation">
<ul>
<li>this is</li>
<li>CSS3 looped</li>
<li>animation</li>
</ul>
</div>
This is the CSS:
#animation {
height: 100%;
width: 100%;
}
#animation ul {
position: relative;
text-align: center;
width: 100%;
}
#animation li {
position: absolute;
left:0;
top:0;
width: 100%;
opacity: 0;
padding: 10px;
}
#animation li:nth-of-type(1) {
-webkit-animation: fadein 6s ease-in-out -4s infinite alternate;
-moz-animation: fadein 6s ease-in-out -4s infinite alternate;
animation:fadein 6s ease-in-out -4s infinite alternate;
}
#animation li:nth-of-type(2) {
-webkit-animation: fadein 6s ease-in-out 0s infinite alternate;
-moz-animation: fadein 6s ease-in-out 0s infinite alternate;
animation: fadein 6s ease-in-out 0s infinite alternate;
}
#animation li:nth-of-type(3) {
-webkit-animation: fadein 6s ease-in-out 4s infinite alternate;
-moz-animation: fadein 6s ease-in-out 4s infinite alternate;
animation: fadein 6s ease-in-out 4s infinite alternate;
}
#-webkit-keyframes fadein {
0% {
opacity: 0;
}
66% {
opacity: 0;
}
76% {
opacity: 1;
}
100% {
opacity: 1;
}
}
#-moz-keyframes fadein {
0% {
opacity: 0;
}
66% {
opacity: 0;
}
76% {
opacity: 1;
}
100% {
opacity: 1;
}
}
#keyframes fadein {
0% {
opacity: 0;
}
66% {
opacity: 0;
}
76% {
opacity: 1;
}
100% {
opacity: 1;
}
}
I am new to CSS3 and with the code I want to stick paragraphs in instead of a couple of words. My question is, when the text fades in, how can you keep it on the screen for eg 10 seconds so someone can read it and the fade out into the next paragraph.
I have used duration and delay, doesn't really seem to work the way I wanted. Any help will be great.
The approach is really simple but you would need to do math as mentioned in Paulie_D's comment. I would leave the choice on whether to use it or not to you. Personally, I don't see anything wrong with this approach or any complexity provided the no. of elements to be faded in/out is static.
The overall approach is as follows:
We have 3 elements/paragraphs and for the example purpose I am going to make them fade-in for the first 3 seconds, stay as-is for the next 10 seconds and fade out for the last. So, for each element we need a total of 16 seconds in animation time.
While the first element has completed its animation and the second or third is being animated, the previous ones should hold the final state (that is faded out). To achieve this, the following need to be done:
Set the animation-duration for all elements such that it is the sum total of animation times for all elements. Here it would be 3*16s = 48s.
Set the keyframes such that each element would remain idle for 32s of the total duration because during this 32s gap the other two elements would be doing their animation. This is achieved by completing the fade-in, the stay and the fade-out all together within 33% of the animation's total duration.
Set animation-delay of second element to be 16s (because it has to start after the first one is completed) and that for the third to be 32s (because first two should complete).
Coming to the keyframes rule itself, as I said earlier the whole animation for one element should complete within 33% of the full duration. So at 6.25% (roughly 3s mark), we fade the element in and then till 26.75% (which is till 13s mark) we make it be at opacity: 1 and then at 33% (that is 16s mark) we completely fade it out.
#animation {
height: 100%;
width: 100%;
}
#animation ul {
position: relative;
text-align: center;
width: 100%;
}
#animation li {
position: absolute;
left: 0;
top: 0;
width: 100%;
opacity: 0;
padding: 10px;
}
#animation li:nth-of-type(1) {
animation: fadein 48s ease-in-out infinite;
}
#animation li:nth-of-type(2) {
animation: fadein 48s ease-in-out 16s infinite;
}
#animation li:nth-of-type(3) {
animation: fadein 48s ease-in-out 32s infinite;
}
#keyframes fadein {
0% {
opacity: 0;
}
6.25% { /* 3s for fade in */
opacity: 1;
}
26.75% { /* roughly 10s for stay as-is */
opacity: 1;
}
33% { /* 3s for fade out */
opacity: 0;
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<div id="animation">
<ul>
<li>This is</li>
<li>CSS3 looped</li>
<li>animation</li>
</ul>
</div>
The basic CSS code for this example looks like this:
.visible {
visibility: visible;
opacity: 1;
transition: opacity 2s linear;
}
.hidden {
visibility: hidden;
opacity: 0;
transition: visibility 0s 2s, opacity 2s linear;
}
When showing the element (by switching to the visible class), we want the visibility:visible to kick in instantly, so it’s ok to transition only the opacity property. And when hiding the element (by switching to the hidden class), we want to delay the visibility:hidden declaration, so that we can see the fade-out transition first. We’re doing this by declaring a transition on the visibility property, with a 0s duration and a delay.
At the end of the fade-out transition, we want to remove the hidden element from the flow, so that it does not leave a blank space in the middle of the page. Sadly we don’t have many options here:
display:none doesn’t work because it will be applied instantly, and
trying to delay it like we did with visibility won’t work;
position:absolute has the exact same issue;
It’s not ideal, but we can use margin-top (it can be transitioned and
thus delayed).
In order to use margin-top to hide the element, we need to have a slightly richer HTML structure:
<div class="visible">
<div>…</div>
</div>
And our CSS code becomes more complex:
.visible,
.hidden {
overflow: hidden;
/* This container should not have padding, borders, etc. */
}
.visible {
visibility: visible;
opacity: 1;
transition: opacity 2s linear;
}
.hidden {
visibility: hidden;
opacity: 0;
transition: visibility 0s 2s, opacity 2s linear;
}
.visible > div,
.hidden > div {
/* Put any padding, border, min-height, etc. here. */
}
.hidden > div {
margin-top: -10000px;
transition: margin-top 0s 2s;
}

How can I change a css property after it has been #keyframe animated?

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