Iterate animation as a group not as individual animations in CSS - css

I've written this CSS code that fades in text boxes and then fades them out consecutively. The text boxes are overlapping. I want to loop this animation infinitely, but when I use the animation-iteration-count function, each individual animation iterates and they overlap. I wish to loop the animation only after the last (third) text box has finished its fade-in fade-out cycle.
.fade-container {
position: relative;
}
.fade-box {
position: absolute;
opacity: 0;
animation: fade 3s ease-in-out forwards;
animation-iteration-count: infinite;
}
#keyframes fade {
0% {
opacity: 0;
}
33% {
opacity: 1;
}
66% {
opacity: 0;
}
100% {
opacity: 0;
}
}
.fade-box:nth-child(1) {
animation-delay: 0s;
}
.fade-box:nth-child(2) {
animation-delay: 2s;
}
.fade-box:nth-child(3) {
animation-delay: 4s;
}
<div class="fade-container">
<div class="fade-box">Box 1</div>
<div class="fade-box">Box 2</div>
<div class="fade-box">Box 3</div>
</div>

Related

CSS fade transition (no jQuery)

I'm trying to create a visual transition between content changes in a toy SPA I'm writing. To that end, I define a simple class for animating the opacity of an element.
.fade {
transition: opacity 1.5s;
}
In my render function, I now change the opacity of my outlet div after content changes like so:
function render(content) {
var outlet = document.getElementById("outlet");
outlet.classList.remove("fade");
outlet.style.opacity = 0;
outlet.innerHTML = content;
outlet.classList.add("fade");
outlet.style.opacity = 1;
}
Unfortunately, the animation never fires. When I delay changing the opacity to 1 via setTimeout for 10ms, say, it works sometimes if I don't change the content again while the animation is still running, indicating a timing issue/race condition.
I used a similar approach in the past to fade out messages, but there I intentionally delayed changing the opacity by a few seconds so users could read the message before it starts fading out.
Pure CSS animation fadeIn
li {
position: absolute;
top: 50%;
left: 50%;
margin-top: -75px;
}
.logo {
width: 300px;
height: 150px;
background: red;
margin-left: -150px;
z-index: 30;
-webkit-animation: fade-in-slogan 4s .2s ease-in forwards;
-moz-animation: fade-in-slogan 4s .2s ease-in forwards;
animation: fade-in-slogan 4s .2s ease-in forwards;
}
.menu {
width: 600px;
height: 150px;
background: blue;
margin-left: -300px;
opacity: 0;
-webkit-animation: fade-in-menu 3s 4s ease-out forwards;
-moz-animation: fade-in-menu 3s 4s ease-out forwards;
animation: fade-in-menu 3s 4s ease-out forwards;
}
#-webkit-keyframes fade-in-slogan {
0% { opacity: 0; }
30% { opacity: 1; }
50% { opacity: 1; }
70% { opacity: 1; }
100% { opacity: 0; }
}
#-webkit-keyframes fade-in-menu {
0% { display: block; opacity: 0; }
30% { display: block; opacity: .3; }
60% { display: block; opacity: .6; }
80% { display: block; opacity: .8; }
100% { display: block; opacity: 1; }
}
<ul class"main">
<li class="logo"></li>
<li class="menu"></li>
</ul>
Try this, I hope this will solve the issue
.fade{
animation-name: example;
animation-duration: 4s;}
#keyframes example {
from {opacity:1}
to {opacity:0;}
}
div{
width:200px;
height:200px;
background:#000;
}
<html>
<head>
</head>
<body>
<div class="fade"></div>
</body>
</html>
I've solved it now inspired by Muhammad's answer. I defined the fade class as follows:
.fade {
animation-name: fadein;
animation-duration: 1.25s;
#keyframes fadein {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
}
Then in the render function, I do
function render(content) {
outlet.classList.remove("fade");
outlet.innerHTML = "";
setTimeout(() => {
outlet.classList.add("fade");
outlet.appendChild(content);
}, 100);
}
Even though this adds an additional delay before the new content actually starts to fade in, it seems the most elegant and concise solution to me.

How to make the second element appear after the first one has disappeared?

I want to make the first square appear after 3s and then it needs to disappear. After it disappears, the second square becomes visible after 11s. How to make the second square appear only after the first one has disappeared after 11 seconds?
.one, .two{
background-color: black;
height: 50px;
width: 50px;
}
.one{
animation: fadein 3s, fadeout 7s ;
}
.two{
animation: fadein 11s, fadeout 17s ;
}
#keyframes fadein {
from { opacity: 0; }
to { opacity: 1; }
}
#keyframes fadeout {
from {
opacity: 1;
}
to {
opacity: 0;
}
}
<div class="one"></div>
<br>
<div class="two"></div>
Use animation-delay maybe?
Also note that you cannot animate the same css attribute in multiple keyframes on the same element. The css defined in the last keyframe will always override the earlier ones. You can try to use % to achieve something similar to what you want.
.one, .two{
background-color: black;
height: 50px;
width: 50px;
opacity: 0;
}
.one{
animation: fadeinout1 10s;
}
.two{
animation: fadeinout2 28s ;
animation-delay: 10s ;
}
#keyframes fadeinout1 {
0%, 100% { opacity: 0; }
30% { opacity: 1; } /*Simulate 3s, out of the whole animation of 10s*/
}
#keyframes fadeinout2 {
0%, 100% { opacity: 0; }
39% { opacity: 1; } /*Simulate 11s, out of the whole animation of 28s*/
}
<div class="one"></div>
<br>
<div class="two"></div>

rewrite my jquery fadein / fadeout using CSS3 only and running infinite

$(function() {
$('.text1').delay(1000).fadeIn(1500);
$('.text1').delay(600).fadeOut(1500);
$('.text2').delay(5000).fadeIn(1500);
$('.text2').delay(600).fadeOut(1500);
$('.text3').delay(10000).fadeIn(1500);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="text1">Lorem Ipsem</div>
<div class="text2">Lorem Ipsem</div>
<div class="text3">Lorem Ipsem</div>
Above is my simple jQuery animation; simple delay -> fadeIn -> delay -> fadeOut. However I find when trying to create a loop, for my animations to run continuously my code becomes way to large and bulky. I am wondering if it's at all possible to rewrite what I have above with CSS3 only, and then using the infinite option CSS allows.
I've gotten close with CSS below code however, I need to completely hide or fadeOut each line of text before new text shows.
#-webkit-keyframes slider {
0% { opacity: 0.4; }
100% { opacity: 1; }
}
#-moz-keyframes slider {
0% { opacity: 0.4; }
100% { opacity: 1; }
}
#-ms-keyframes slider {
0% { opacity: 0.4; }
100% { opacity: 1; }
}
.slider {
-webkit-animation: slider 1s alternate infinite;
-moz-animation: slider 1s alternate infinite;
-ms-animation: slider 1s alternate infinite;
}
<div class="slider">Lorem Ipsum</div>
As stated in other answers you can not achieve what you are asking using pure CSS solutions.
You can a solution like to an extensible approach (in case you want have many more child elements).
$("#fadeinout div").on("animationend", function() {
_this = jQuery(this);
// remove animation class
_this.removeClass("animate");
// If there is no next element then go to first one otherwise choose next element
var next = (_this.next().length < 1) ? _this.prevAll(':first-child') : _this.next();
// Add class to the new element
next.addClass("animate");
});
#fadeinout div {
width: 100px;
height: 100px;
background: red;
opacity: 0;
margin: 5px;
}
.animate {
animation-name: fadeinout;
animation-duration: 4s;
animation-delay: 0s;
}
#keyframes fadeinout {
50% {
opacity: 1;
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="fadeinout">
<div class='animate'></div>
<div></div>
<div></div>
<div></div>
</div>
This is the same example with many child elements animated: https://jsfiddle.net/j4zdgopr/1/
You can't really time the animation of multiple elements in css only. Well you could probably fake it with something like:
div {
width: 50px;
height: 50px;
background: #f00;
opacity: 0;
}
#d1 {
animation: d1 10s infinite;
}
#d2 {
animation: d2 10s infinite;
}
#d3 {
animation: d3 10s infinite;
}
#d4 {
animation: d4 10s infinite;
}
#keyframes d1 {
0% { opacity: 0; }
5% { opacity: 1; }
20% { opacity: 1; }
25% { opacity: 0; }
}
#keyframes d2 {
25% { opacity: 0; }
30% { opacity: 1; }
45% { opacity: 1; }
50% { opacity: 0; }
}
#keyframes d3 {
50% { opacity: 0; }
55% { opacity: 1; }
70% { opacity: 1; }
75% { opacity: 0; }
}
#keyframes d4 {
75% { opacity: 0; }
80% { opacity: 1; }
95% { opacity: 1; }
100% { opacity: 0; }
}
<div id="d1"></div>
<div id="d2"></div>
<div id="d3"></div>
<div id="d4"></div>
...but I would recommend against it. First of all I don't think the timing will be reliable - ie. it will get out of sync. Second your code will most likely be even more bulky than what you have.
So I would recommend a combination of simple CSS transitions and JS like this:
var curslide = 0;
var slides = $("#slider div");
var nextslide = function() {
slides.removeClass('shown');
if (curslide >= slides.length) curslide = 0;
slides.eq(curslide).addClass('shown');
curslide++;
setTimeout(nextslide, 3000);
}
nextslide();
#slider div {
width: 50px;
height: 50px;
background: #f00;
opacity: 0;
transition: opacity .5s linear;
}
#slider div.shown {
opacity: 1;
transition: opacity .5s .5s linear;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="slider">
<div id="d1"></div>
<div id="d2"></div>
<div id="d3"></div>
<div id="d4"></div>
</div>
With this solution you can add as many frames as needed without modifying the css or js.
I'd try playing with animation-delay, but I think it only applies to the first time the animation is run. After that, unless you write one animation for each .text element, they'll all fade in/out with the same frequency.
Would:
setInterval(function(){
$('.text1').delay(5000).fadeIn(1500);
$('.text2').delay(5000).fadeIn(1500);
$('.text3').delay(5000).fadeIn(1500);
$('.text1').delay(1000).fadeOut(1500);
$('.text2').delay(5000).fadeOut(1500);
}, 11500);
get you somewhere close?

Looping a fade in animation

Im trying to animate the gold blocks in the JSFiddle.
All gold blocks should be invisible, then the first one fades in, followed by the second, then the third fourth and fifth, giving a tower of gold blocks.
#keyframes twinkle {
0% {
opacity: 0;
}
10% {
opacity: 1;
}
100% {
opacity: 1;
}
}
It works fine for the first round of the animation. But when it loops all gold blocks are on.
Any ideas where I am going wrong?
You werent resetting your loop before it queued again. here is a working fiddle with the css changes below.
#keyframes twinkle {
0% {
opacity: 0;
}
20% {
opacity: 1;
}
30% {
opacity: 1;
}
40% {
opacity: 1;
}
60% {
opacity: 1;
}
70% {
opacity: 1;
}
80% {
opacity: 1;
}
90% {
opacity: 0;
}
}
edit 1:
So I had to modify a few things within the fiddle. First there is now a small bit of JS so it resets.
setInterval(function (){
window.elm = document.getElementById('main-block'),
window.newone = elm.cloneNode(true);
elm.parentNode.replaceChild(window.newone, window.elm);
}, 5000);
Here is the modified HTMl markup.
<div id="main-block">
<div class="block one"></div>
<div class="block two"></div>
<div class="block three"></div>
<div class="block four"></div>
<div class="block five"></div>
</div>
And the final CSS
.block{
background: gold;
margin: 1rem;
width: 30px;
height: 30px;
opacity: 0;
}
#keyframes twinkle {
0% {
opacity: 0;
}
25% {
opacity: 1;
}
100% {
opacity: 1;
}
}
.one{
animation: twinkle 5s ease-in-out infinite;
}
.two{
animation: twinkle 5s 1s ease-in-out infinite;
}
.three{
animation: twinkle 5s 2s ease-in-out infinite;
}
.four{
animation: twinkle 5s 3s ease-in-out infinite;
}
.five{
animation: twinkle 5s 4s ease-in-out infinite;
}
https://jsfiddle.net/kx7bf19g/4/
You must reset the opacity to 0.
Try this, played around with key frames :)
5 different keyframes were created
Just adjust them a little bit.
https://jsfiddle.net/y7q1jj7g/2/ - working fiddle
This is the first keyframe:
#keyframes twinkle {
9% { opacity: 0; }
10% { opacity: 1; }
20% { opacity: 1; }
99% { opacity: 1; }
100% { opacity: 0; }
}
According to mozilla the delay is only applied initially, when the animation is applied. This is done on page load by the browser, applying the css. Thus, the initial delay is not loopable.
There is a scripted solution that toggles a class in order to start and stop the animation using a toggle.
Here's a fiddle demonstrating the principle.
However, removing and adding a CSS class in two consecutive statements does not work - it gets optimized away by a rendering path. I've tried setTimeout and requestAnimationFrame but to no avail.

CSS3 Animation Repeat pause before next iteration [duplicate]

I am using WOW.js and animate.css, right now I am running my CSS to Infinite. I would like know how can I make my class run for 3 seconds stop and start again to infinite?
My html:
<img src="images/fork.png" class="fork wow rubberBand" >
My CSS class:
.fork {
position: absolute;
top: 38%;
left: 81%;
max-width: 110px;
-webkit-animation-iteration-count: infinite ;
-webkit-animation-delay: 5s;
}
The solution can be in JS or CSS3.
With pure CSS3 animations, one way to add a delay between every single iteration of the animation would be to modify the keyframes setting such that they produce the required delay.
In the below snippet, the following is what is being done:
The whole duration of the animation is 6 seconds. In order to have the delay, the whole duration should be the duration for which your animation actually runs + time delay. Here, the animation actually runs for 3s, we need a 3s delay and so the duration is set as 6 seconds.
For the first 50% of the animation (that is, 3 seconds), nothing happens and the element basically holds its position. This gives the appearance of the 3 second delay being applied
For the next 25% of the animation (that is, 1.5 seconds) the element moves down by 50px using transform: translateY(50px).
For the final 25% of the animation (that is, last 1.5 seconds) the element moves up by 50px using transform: translate(0px) (back to its original position).
The whole animation is repeated infinite number of times and each iteration will end up having a 3 second delay.
div{
height: 100px;
width: 100px;
border: 1px solid;
animation: move 6s infinite forwards;
}
#keyframes move{
0% { transform: translateY(0px);}
50% { transform: translateY(0px);}
75% { transform: translateY(50px);}
100% { transform: translateY(0px);}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<div>Some content</div>
The animation-delay property introduces a delay only for the first iteration and hence it cannot be used to add delays between every iteration. Below is a sample snippet illustrating this.
div{
height: 100px;
width: 100px;
border: 1px solid;
animation: move 6s infinite forwards;
animation-delay: 3s;
}
#keyframes move{
0% { transform: translateY(0px);}
50% { transform: translateY(50px);}
100% { transform: translateY(0px);}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<div>Some content</div>
LIke this
html
<div class="halo halo-robford-animate"></div>
css
body{
background: black;
}
.halo{
width: 263px;
height: 77px;
background: url('http://i.imgur.com/3M05lmj.png');
}
.halo-robford-animate{
animation: leaves 0.3s ease-in-out 3s infinite alternate;
-webkit-animation: leaves 0.3s ease-in-out 3s infinite alternate;
-moz-animation: leaves 0.3s ease-in-out 3s infinite alternate;
-o-animation: leaves 0.3s ease-in-out 3s infinite alternate;
}
#-webkit-keyframes leaves {
0% {
opacity: 1;
}
50% {
opacity: 0.5;
}
100% {
opacity: 1;
}
}
#-moz-keyframes leaves {
0% {
opacity: 1;
}
50% {
opacity: 0.5;
}
100% {
opacity: 1;
}
}
#-o-keyframes leaves {
0% {
opacity: 1;
}
50% {
opacity: 0.5;
}
100% {
opacity: 1;
}
}
#keyframes leaves {
0% {
opacity: 1;
}
50% {
opacity: 0.5
}
100% {
opacity: 1;
}
}
jsfiddle

Resources