CSS Animation keyframe calculations - css

I'm working on a css text slider animation. It originally had 5 items but I've removed one so now there are 4.
I'm having trouble with the keyframe calculations. There is a bit of a pause when the last item slides out and the first item slides back in again. It was all working fine when it had 5 items but removing one has affected the timings.
HTML:
<div class="content-slider">
<div class="slider">
<div class="mask">
<ul>
<li class="anim1">
<div class="quote"> Service to 200+ countries</div>
</li>
<li class="anim2">
<div class="quote">Same day delivery services</div>
</li>
<li class="anim3">
<div class="quote">Easy booking tools.</div>
</li>
<li class="anim4">
<div class="quote">Rated great.</div>
</li>
</ul>
</div>
</div>
</div>
CSS:
html,
body {
font-family: 'Droid Serif', serif;
}
h1 {
font-size: 60px;
text-align: center;
}
.content-slider {
width: 100%;
height: 360px;
}
.slider {
height: 320px;
width: 680px;
margin: 40px auto 0;
overflow: visible;
position: relative;
}
.mask {
overflow: hidden;
height: 320px;
}
.slider ul {
margin: 0;
padding: 0;
position: relative;
}
.slider li {
width: 680px;
height: 320px;
position: absolute;
right: -325px;
list-style: none;
}
.slider .quote {
font-size: 40px;
font-style: italic;
text-align:center;
}
.slider li.anim1 {
animation: cycle 12s linear infinite;
}
.slider li.anim2 {
animation: cycle2 12s linear infinite;
}
.slider li.anim3 {
animation: cycle3 12s linear infinite;
}
.slider li.anim4 {
animation: cycle4 12s linear infinite;
}
#keyframes cycle {
0% {
right: 0px;
}
4% {
right: 0px;
}
16% {
right: 0px;
opacity: 1;
z-index: 0;
}
20% {
right: 325px;
opacity: 0;
z-index: 0;
}
21% {
right: -325px;
opacity: 0;
z-index: -1;
}
50% {
right: -325px;
opacity: 0;
z-index: -1;
}
92% {
right: -325px;
opacity: 0;
z-index: 0;
}
96% {
right: -325px;
opacity: 0;
}
100% {
right: 0px;
opacity: 1;
}
}
#keyframes cycle2 {
0% {
right: -325px;
opacity: 0;
}
16% {
right: -325px;
opacity: 0;
}
20% {
right: 0px;
opacity: 1;
}
24% {
right: 0px;
opacity: 1;
}
36% {
right: 0px;
opacity: 1;
z-index: 0;
}
40% {
right: 325px;
opacity: 0;
z-index: 0;
}
41% {
right: -325px;
opacity: 0;
z-index: -1;
}
100% {
right: -325px;
opacity: 0;
z-index: -1;
}
}
#keyframes cycle3 {
0% {
right: -325px;
opacity: 0;
}
36% {
right: -325px;
opacity: 0;
}
40% {
right: 0px;
opacity: 1;
}
44% {
right: 0px;
opacity: 1;
}
56% {
right: 0px;
opacity: 1;
z-index: 0;
}
60% {
right: 325px;
opacity: 0;
z-index: 0;
}
61% {
right: -325px;
opacity: 0;
z-index: -1;
}
100% {
right: -325px;
opacity: 0;
z-index: -1;
}
}
#keyframes cycle4 {
0% {
right: -325px;
opacity: 0;
}
56% {
right: -325px;
opacity: 0;
}
60% {
right: 0px;
opacity: 1;
}
64% {
right: 0px;
opacity: 1;
}
76% {
right: 0px;
opacity: 1;
z-index: -1;
}
80% {
right: 325px;
opacity: 0;
z-index: -1;
}
81% {
right: -325px;
opacity: 0;
z-index: -1;
}
100% {
right: -325px;
opacity: 0;
z-index: -1;
}
}
It's the final cycle4 animation that I've tried tweaking but I can't get the smooth transition from last to first working as it was.
Here's a codepen example

If you want your animation to remain 12s long then you need to realise that with 4 items, each item has 3s worth of animation time, and that every 1s of the animation is 8.33333% of the total animation time.
If you struggle visualising this kind of thing I'd advise setting up a spreadsheet or something to do the calculations:
You can then easily see the percentages of your keyframes as you change parameters such as the animation length and in/out time. Anyway, here's the snippet:
html,
body {
font-family: 'Droid Serif', serif;
}
h1 {
font-size: 60px;
text-align: center;
}
.content-slider {
width: 100%;
height: 360px;
}
.slider {
height: 320px;
width: 680px;
margin: 40px auto 0;
overflow: visible;
position: relative;
}
.mask {
overflow: hidden;
height: 320px;
}
.slider ul {
margin: 0;
padding: 0;
position: relative;
}
.slider li {
width: 680px;
height: 320px;
position: absolute;
right: -325px;
list-style: none;
}
.slider .quote {
font-size: 40px;
font-style: italic;
text-align: center;
}
.slider li.anim1 {
animation: cycle 12s linear infinite;
}
.slider li.anim2 {
animation: cycle2 12s linear infinite;
}
.slider li.anim3 {
animation: cycle3 12s linear infinite;
}
.slider li.anim4 {
animation: cycle4 12s linear infinite;
}
#keyframes cycle {
0% {
right: -325px;
opacity: 0;
z-index: -1;
}
4.2% {
right: 0px;
opacity: 1;
z-index: 0;
}
20.8% {
right: 0px;
opacity: 1;
}
25% {
right: 325px;
opacity: 0;
z-index: -1;
}
100% {
right: -325px;
opacity: 0;
}
}
#keyframes cycle2 {
0% {
right: -325px;
opacity: 0;
}
25% {
right: -325px;
opacity: 0;
}
29.2% {
right: 0px;
opacity: 1;
}
45.8% {
right: 0px;
opacity: 1;
}
50% {
right: 325px;
opacity: 0;
z-index: -1;
}
100% {
right: -325px;
opacity: 0;
z-index: -1;
}
}
#keyframes cycle3 {
0% {
right: -325px;
opacity: 0;
}
50% {
right: -325px;
opacity: 0;
}
54.2% {
right: 0px;
opacity: 1;
}
70.8% {
right: 0px;
opacity: 1;
}
75% {
right: 325px;
opacity: 0;
z-index: -1;
}
100% {
right: -325px;
opacity: 0;
z-index: -1;
}
}
#keyframes cycle4 {
0% {
right: -325px;
opacity: 0;
}
74.99% {
right: -325px;
opacity: 0;
}
79.2% {
right: 0px;
opacity: 1;
}
95.8% {
right: 0px;
opacity: 1;
}
100% {
right: 325px;
opacity: 0;
z-index: -1;
}
}
<div class="content-slider">
<div class="slider">
<div class="mask">
<ul>
<li class="anim1">
<div class="quote"> Service to 200+ countries</div>
</li>
<li class="anim2">
<div class="quote">Same day delivery services</div>
</li>
<li class="anim3">
<div class="quote">Easy booking tools.</div>
</li>
<li class="anim4">
<div class="quote">Rated great.</div>
</li>
</ul>
</div>
</div>
</div>

Related

Animate closing side panel on right side

So I got my right sidebar animating nicely coming in, but how would I animate out as of right now it just closing without any animation?
.calendarQuickpanelContainer {
animation: animateopen 0.6s;
bottom: 0;
display: none;
position: fixed;
top: 0;
right: 0;
width: 462px;
z-index: 100;
}
.calendarQuickpanel {
display: block;
}
#keyframes animateopen {
0% {
right: -462px;
opacity: 0;
}
100% {
right: 0;
opacity: 1;
}
}
Thanks
Animation is not very good, better use transition here. You have better control because you can use a class to toggle states.
function toggleFunction() {
var element = document.getElementById("sidebar");
element.classList.toggle("active");
}
#sidebar {
background: lightblue;
width: 250px;
position: fixed;
top: 0;
left: 0;
bottom: 0;
transform: translateX(-260px);
opacity: 0;
transition: transform 1s, opacity 1s;
}
#sidebar.active {
transform: translateX(0px);
opacity: 1;
}
button {
float: right;
margin: 32px;
}
<div id="sidebar">
</div>
<button onclick="toggleFunction()">toggle sidebar</button>

Css Animation - animation delay

Update - The pen below has been updated to show the end results.
I am trying to mimic signal animation using css animation but I cant seem to grasp the idea of animation delay. If you look here
http://codepen.io/anon/pen/YwZOmK?editors=110
.real-time-animation {
margin-top: 20px;
position: relative;
transform: scale(0.5) rotate(45deg);
transform-origin: 5% 0%;
}
.real-time-animation>div {
animation: sk-bouncedelay 3s infinite forwards;
}
.circle1 {
animation-delay: 2s;
}
.circle2 {
animation-delay: 1s;
}
#keyframes sk-bouncedelay {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
.circle {
position: relative;
width: 16em;
height: 16em;
border-radius: 50%;
background: transparent;
border: 20px solid transparent;
border-top-color: darkblue;
position: absolute;
top: 0;
left: 0;
opacity: 0;
}
.circle2 {
top: 40px;
width: 12em;
height: 12em;
left: 33px;
}
.circle3 {
top: 80px;
width: 8em;
height: 8em;
left: 66px;
}
<div class="real-time-animation">
<div class="circle circle1"> </div>
<div class="circle circle2"> </div>
<div class="circle circle3"> </div>
</div>
You should be able to understand what I am trying to accomplish. I want to start from showing nothing, then after 1 sec show the first bar, then after 1 sec, show the 2nd bar and finally after another 1 sec show the 3rd bar.
My solution:
http://codepen.io/anon/pen/JGWmJg?editors=110
.real-time-animation{
margin-top: 20px;
position: relative;
transform: scale(0.5) rotate(45deg);
transform-origin: 5% 0%;
}
.circle1, .circle2, .circle3{
animation: 4s infinite ease-in;
animation-delay: 1s;
}
.circle1{
animation-name: circle1;
}
.circle2{
animation-name: circle2;
}
.circle3{
animation-name: circle3;
}
#keyframes circle1 {
0%{
opacity: 0;
}
25%{
opacity: 0;
}
50%{
opacity: 0;
}
75%{
opacity: 1;
}
100% {
opacity: 0;
}
}
#keyframes circle2 {
0%{
opacity: 0;
}
25%{
opacity: 0;
}
50%{
opacity: 1;
}
75% {
opacity: 1;
}
100%{
opacity: 0;
}
}
#keyframes circle3 {
0%{
opacity: 0;
}
25%{
opacity: 1;
}
50%{
opacity: 1;
}
75% {
opacity: 1;
}
100%{
opacity: 0;
}
}
.circle {
position: relative;
width: 16em; height: 16em;
border-radius: 50%;
background: transparent;
border: 20px solid transparent;
border-top-color: darkblue;
position: absolute;
top: 0;
left: 0;
opacity: 0;
}
.circle2{
top: 40px;
width: 12em;
height: 12em;
left: 33px;
}
.circle3{
top: 80px;
width: 8em;
height: 8em;
left: 66px;
}
You can change the speed of the animation duration: "animation: 4s infinite ease-in;"
As I understand your question animated opacity needs to be like this:
Progress \ Element
.circle1
.circle2
.circle3
0%
0
0
0
25%
0
0
1
50%
0
1
1
75%
1
1
1
100%
0
0
0
The opacity property is clamped which means if you set negative values, it will have the same effect as setting it to 0. The same goes for values larger than 1.
Using this property, we can subtract a constant value from predefined CSS variables and use that as opacity.
.real-time-animation {
zoom: 10;
width: 8px;
height: 8px;
position: relative;
display: inline-block;
}
.real-time-animation>.circle {
animation: circle 4s infinite ease-in;
}
.circle1 {
--circle: 1;
}
.circle2 {
--circle: 2;
}
.circle3 {
--circle: 3;
}
#keyframes circle {
0%, 100% {
opacity: 0;
}
25% {
opacity: calc(var(--circle) - 2);
}
50% {
opacity: calc(var(--circle) - 1);
}
75% {
opacity: 1;
}
}
.circle {
border-radius: 50%;
background: transparent;
border: 1px solid transparent;
border-top-color: darkblue;
position: absolute;
margin: 0;
box-sizing: border-box;
top: 100%;
left: 0%;
width: calc(16px - (var(--circle) - 1)*4px);
height: calc(16px - (var(--circle) - 1)*4px);;
transform: rotate(45deg) translate(-50%, -50%);
transform-origin: 0 0;
}
<div class="real-time-animation">
<div class="circle circle1"> </div>
<div class="circle circle2"> </div>
<div class="circle circle3"> </div>
</div>

CSS3 animation - changing words to infinity without rewind

It's my first time experimenting with css3 animations and I have a question regarding the following setup:
Link to codepen
After item3 the animation rewinds to item1. I wonder if it's possible to let follow the item1 after the item3 without this rewinding, so that item3 also moves to the top and item1 slides in from the bottom again, and so on and on?
HTML
<div id="change">
<span>item1</span>
<span>item2</span>
<span>item3</span>
</div>
CSS
#change {
overflow: hidden;
height: 58px;
color: black;
font-size: 3em;
}
#change span {
position: relative;
display: block;
animation: myAnim 10s ease infinite 0s;
-webkit-animation: myAnim 10s ease infinite 0s;
}
#keyframes myAnim {
0% { top: 0px; }
20% { top: 0px; }
35% { top: -58px; }
55% { top: -58px; }
70% { top: -116px; }
90% { top: -116px; }
100% { top: 0px; }
}
#-webkit-keyframes myAnim {
0% { top: 0px; }
20% { top: 0px; }
35% { top: -58px; }
55% { top: -58px; }
70% { top: -116px; }
90% { top: -116px; }
100% { top: 0px; }
}
Unfortunately, there doesn't seem to be an easy way to do this. If we were using an image, you could easily just take advantage of repeat and force the beginning of the element to start at the end of the element. However, since we aren't using an image, the only solution I can think of would be to use the first element as the last element.
UPDATED EXAMPLE HERE
HTML
<div id="change">
<span>item1</span>
<span>item2</span>
<span>item3</span>
<span>item1</span> <!-- The first element is used as the last element-->
</div>
Modified CSS
#-webkit-keyframes myAnim {
0% { top: 0; }
20% { top: 0; }
35% { top: -58px; }
55% { top: -58px; }
70% { top: -116px; }
90% { top: -116px; }
100% { top: -172px; }
}
it didn't let me rest, so i figured out another solution. with no doubled item1, but the missing part in this is that it doesn't start with the item1 being already there at the beginning.
Link to codepen
HTML
<div id="change">
<span>item1</span>
<span>item2</span>
<span>item3</span>
</div>
CSS
#change {
overflow: hidden;
height: 58px;
color: black;
font-size: 3em;
position: relative;
}
#change span {
position: absolute;
display: block;
animation: myAnim 9s ease infinite 0s;
-webkit-animation: myAnim 9s ease infinite 0s;
}
#change span:nth-of-type(2) {
animation-delay: 3s;
-webkit-animation-delay: 3s;
top: 58px;
}
#change span:nth-of-type(3) {
animation-delay: 6s;
-webkit-animation-delay: 6s;
top: 58px;
}
#keyframes myAnim {
0% { top: 58px; }
15% { top: 0px; }
33% { top: 0px; }
48% { top: -58px; opacity:1; }
60% { top: -58px; opacity: 0; }
80% { top: 58px; opacity: 0; }
100% { top: 58px; opacity: 1; }
}
#-webkit-keyframes myAnim {
0% { top: 58px; }
15% { top: 0px; }
33% { top: 0px; }
48% { top: -58px; opacity:1; }
60% { top: -58px; opacity: 0; }
80% { top: 58px; opacity: 0; }
100% { top: 58px; opacity: 1; }
}

Keyframe Animations not in sync

Works correctly on my local filesystem, not from a server. It is starting out of sync for some reason. Thanks for any help. Only vendor prefixed for WebKit. Tested in Chrome 26.Demo: http://cssdesk.com/jjqKK
HTML:
<ul class="slides">
<li><img src="http://placehold.it/200x100" /><span class="caption">Image 1</span></li>
<li><img src="http://placehold.it/200x100" /><span class="caption">Image 2</span></li>
<li><img src="http://placehold.it/200x100" /><span class="caption">Image 3</span></li>
</ul>
CSS:
ul.slides{
position: relative;
background: #000;
height: 100px;
width: 200px;
padding: 0;
}
ul.slides li{
position: absolute;
left: 0px;
top: 0px;
right: 0px;
bottom: 0px;
height: inherit;
width: inherit;
padding: 0;
margin: 0;
-webkit-animation: slideshow 9s linear infinite;
}
ul.slides.clickpause:active li{
-webkit-animation-play-state:paused;
}
ul.slides li:nth-child(1){ -webkit-animation-delay: 0s; }
ul.slides li:nth-child(2){ -webkit-animation-delay: 3s; }
ul.slides li:nth-child(3){ -webkit-animation-delay: 6s; }
#-webkit-keyframes slideshow{
0%{
opacity: 0;
z-index: 2;
}
3%{
opacity: 1;
}
30%{
opacity: 1;
}
33%{
opacity: 0;
}
34%{
z-index: 1;
}
100%{
opacity: 0;
}
}
ul.slides li img{
position: absolute;
left: 0px;
top: 0px;
right: 0px;
bottom: 0px;
padding: 0;
margin: 0
}
ul.slides li span{
position: absolute;
left: 0px;
right: 0px;
bottom: 0px;
background: rgba(40, 40, 40, 0.8);
color: #FFF;
padding: 5px
}
Demo: http://cssdesk.com/jjqKK
Please no answers that use JavaScript. Thanks!
Your animations might not always start at the same time.
I've found that negative delays work really well with keeping things in sync. With this technique, each animation will load at the same time, but some parts start in the past. Check out the jsbin example:
http://jsbin.com/EreYIdE/2/edit
edited to add example inline:
ul {
background: #000;
height: 100px;
padding: 0;
position: relative;
width: 200px;
}
li {
height: inherit;
margin: 0;
opacity: 0;
padding: 0;
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
width: inherit;
-webkit-animation: slideshow 9s linear infinite;
animation: slideshow 9s linear infinite;
}
li:nth-child(1) {
-webkit-animation-delay: -9s;
animation-delay: -9s;
}
li:nth-child(2) {
-webkit-animation-delay: -6s;
animation-delay: -6s;
}
li:nth-child(3) {
-webkit-animation-delay: -3s;
animation-delay: -3s;
}
#-webkit-keyframes slideshow {
0% {
opacity: 0;
}
3% {
opacity: 1;
}
30% {
opacity: 1;
}
33% {
opacity: 0;
}
100% {
opacity: 0;
}
}
#keyframes slideshow {
0% {
opacity: 0;
}
3% {
opacity: 1;
}
30% {
opacity: 1;
}
33% {
opacity: 0;
}
100% {
opacity: 0;
}
}
img {
margin: 0;
padding: 0;
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
}
span {
background: rgba(40, 40, 40, 0.8);
color: #fff;
padding: 5px;
position: absolute;
right: 0;
bottom: 0;
left: 0;
}
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
<title>JS Bin</title>
</head>
<body>
<ul>
<li>
<img src="http://placehold.it/200x100">
<span>Image 1</span>
<li>
<img src="http://placehold.it/200x100">
<span>Image 2</span>
<li>
<img src="http://placehold.it/200x100">
<span>Image 3</span>
</ul>
</body>
</html>
You'll have to add an animation trigger using javascript
Javascript demo
window.onload = function (){ }
or
jQuery demo
$(window).load(function(){})
as CSS3 animations and transitions start immediately before document load.

css3 Slider auto rotate

I have an accordion slider. which is using CSS3 is their a way to make the slider auto rotate with out using jquery but only with pure css3 animations?
Here is the URL to my site.
Like this?
http://jsfiddle.net/coma/bXDHE/30/
HTML
<div class="neat">
<div>
<img src="http://www.menucool.com/slider/prod/image-slider-4.jpg"/>
<img src="http://blogs.mathworks.com/pick/files/zebrainpastelfield.png"/>
<img src="http://www.freewarepocketpc.net/wp7/img/image-effecter-free.png"/>
<img src="http://www.poyraz.gen.tr/wp-content/uploads/images_4781_1.jpg"/>
</div>
</div>
CSS
div.neat {
font-size: 500px;
width: 1em;
height: 200px;
overflow: hidden;
}
div.neat > div {
position: relative;
left: 0;
width: 4em;
-webkit-animation: loop 10s infinite;
-moz-animation: loop 10s infinite;
}
div.neat > div > img {
width: 1em;
display: block;
float: left;
}
#-webkit-keyframes loop {
0% { left: 0; }
20% { left: 0; }
25% { left: -1em; }
45% { left: -1em; }
50% { left: -2em; }
70% { left: -2em; }
75% { left: -3em; }
95% { left: -3em; }
}
#-moz-keyframes loop {
0% { left: 0; }
20% { left: 0; }
25% { left: -1em; }
45% { left: -1em; }
50% { left: -2em; }
70% { left: -2em; }
75% { left: -3em; }
95% { left: -3em; }
}

Resources