Mike
Mike

Reputation: 5826

CSS3 keyframe progress bar

When you see the fiddle you will see that the animation is somehow jumpy. It should got from left to right to 100% width and then squeeze back to 0% width on the right side. How to fix that?

http://jsfiddle.net/j44gbwna/

div:after {
    content: "";        
    height: 3px;
    background: red;        
    position: absolute;
    animation: loader 2s;
    -webkit-animation: loader 2s;
    animation-iteration-count: infinite;
    -webkit-animation-iteration-count: infinite;
    transition-timing-function: linear;
    -webkit-transition-timing-function: linear;
    bottom: 0px;        
    margin-left: 0;
}

@keyframes loader {
    0% {left: 0px;}
    99% { left: 100%;} 
}

@-webkit-keyframes loader {
    0% {width: 0%;left:0;}
    50% { width: 100%;} 
    99% { width: 0%;right:0;} 
}

Upvotes: 1

Views: 7492

Answers (2)

Shomz
Shomz

Reputation: 37711

When doing CSS keyframe animations, try to define as many properties as you can in all the steps, because when you introduce a new property mid-animation, it usually takes the default/initial value which is sometimes different from what you'd expect:

@-webkit-keyframes loader {
    0% {width: 0%;left:0;right:0}
    50% { width: 100%;left:0;right:0} 
    99% { width: 0%;left:100%;right:0} 
}

http://jsfiddle.net/j44gbwna/3/

div:after {
	content: "";
	/* width: 40px; */
    height: 3px;
    background: red;
    
	position: absolute;
    animation: loader 2s;
    -webkit-animation: loader 2s;
    animation-iteration-count: infinite;
    -webkit-animation-iteration-count: infinite;
    transition-timing-function: linear;
    -webkit-transition-timing-function: linear;
	bottom: 0px;
    
	margin-left: 0;
}

@keyframes loader {
    0% {width: 0%;left:0;right:0}
    50% { width: 100%;left:0;right:0} 
    99% { width: 0%;left:100%;right:0} 
}

@-webkit-keyframes loader {
    0% {width: 0%;left:0;right:0}
    50% { width: 100%;left:0;right:0} 
    99% { width: 0%;left:100%;right:0} 
}
<div></div>

Upvotes: 4

Adam Jenkins
Adam Jenkins

Reputation: 55792

I came up with this one while playing around. Not exactly what you were looking for (which is in the second code snippet), but it produces a neat little effect.

@-webkit-keyframes loader {
    0% {width: 0%;right: 100%;}
    50% { width: 100%;} 
    99% { width: 0%; right:0;} 
}

div:after {
	content: "";
	/* width: 40px; */
    height: 3px;
    background: red;
    
	position: absolute;
    animation: loader 2s;
    -webkit-animation: loader 2s;
    animation-iteration-count: infinite;
    -webkit-animation-iteration-count: infinite;
    transition-timing-function: linear;
    -webkit-transition-timing-function: linear;
	bottom: 0px;
    
	margin-left: 0;
}

@keyframes loader {
    0% {left: 0px;}
    99% { left: 100%;} 
}

@-webkit-keyframes loader {
    0% {width: 0%;right: 100%;}
    50% { width: 100%;} 
    99% { width: 0%; right:0;} 
}
<div></div>

It has to do with the fact that you are trying to animate a property (right) for which you defined no start value (and the way left and right values are treated on position: absolute elements). It get's complicated. The easiest thing to do is to always have the loader at 100% width and just use transforms to display it correctly:

div { 
    overflow:hidden;
    position: absolute;
    bottom:0; left:0; right:0;
    height: 4px;
}

div:after {
	content: "";
	/* width: 40px; */
    height: 3px;
    background: red;
    
	position: absolute;
    animation: loader 2s;
    -webkit-animation: loader 2s;
    animation-iteration-count: infinite;
    -webkit-animation-iteration-count: infinite;
    transition-timing-function: linear;
    -webkit-transition-timing-function: linear;
	bottom: 0px;
    left:0; width:100%;
	margin-left: 0;
}

@-webkit-keyframes loader {
    0% {transform: translateX(-100%);}
    100% {transform: translateX(100%);} 
}
<div></div>

Upvotes: 4

Related Questions