Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CSS animate a div with absolute positioning from left 0 to right 0

Consider this sample.

http://jsfiddle.net/dfabulich/ncbzz5zu/3/

<html>
<body>
<style>
.container {
    position: relative;
    width: 80%;
    height: 100px;
    border: 1px solid black;
}

@keyframes slide {
  from { background-color: red; left: 0; }
  to { background-color: blue; right: 0; }
}

.animated {
    position: absolute;
    width: 20%;
    height: 100%;
    top: 0;
    background-color: red;
    animation-duration: 3s;
    animation-name: slide;
    animation-iteration-count: infinite;
}

</style>
<div class=container>
<div class=animated>
</div></div>

Expected: The red rectangle should smoothly animate from left to right as the color changes from red to blue.

Actual: In Chrome/Firefox, the red rectangle slowly changes color to purple, then teleports from left to right without animating, and then slowly changes from purple to blue. In Safari, the rectangle appears on the right and never moves from there, while animating from red to blue.

Why is this happening? How can I fix it? (I need to fix it in CSS… no JS, no jQuery.)

like image 466
Dan Fabulich Avatar asked May 31 '17 21:05

Dan Fabulich


2 Answers

You need to animate one property or the other. You can just animate left and either use left: calc(100% - elemWidth) (where elemWidth is the width of the element) or left: 100%; transform: translateX(-100%); if the width of the element is unknown.

Also need to animate background color.

.container {
	position: relative;
	width: 80%;
	height: 100px;
	border: 1px solid black;
}

.animated {
	position: absolute;
	width: 20%;
	height: 100%;
	top: 0;
	background-color: red;
	animation: 3s linear 0s slide infinite;
}

@keyframes slide {
  from { left: 0; }
  to {
    left: 100%;
    transform: translateX(-100%);
    background: blue;
  }
}
<div class=container>
<div class=animated>
</div></div>
like image 54
Michael Coker Avatar answered Sep 23 '22 10:09

Michael Coker


The problem is that you start animating property left, but then replace it with right in the end of animation, that's why it jumps. You should keep animating the same property to get the step by step animation progression.

.container {
    position: relative;
    width: 80%;
    height: 100px;
    border: 1px solid black;
}

@keyframes slide {
  from { background-color: red; left: 0; }
  to { background-color: blue; left: 80%; }
}

.animated {
    position: absolute;
    width: 20%;
    height: 100%;
    top: 0;
    background-color: red;
    animation-duration: 3s;
    animation-name: slide;
    animation-iteration-count: infinite;
}
<div class="container"><div class="animated"></div></div>
like image 34
Karen Grigoryan Avatar answered Sep 21 '22 10:09

Karen Grigoryan