6

I'm trying to improve my animation performance using css transforms to translate the position of an element inside a 100% width wrapper. So it enters the screen from the lefthand side and exits on the right, before repeating the animation.

I figured I could use percentages for this animation. what I am finding is that translate is relative to the object you are animating.

So, if you have an object that is 100px wide and you set the animation as follows:

@keyframes moveme {
  0% { transform: translate(-100px, 150px) }
  100% { transform: translate(100%, 100px) }
}

The object will move 200% of the objects width, so 200px.

Is there a fix to make an object travel to the width of the container, using css transform in keyframe animation?

Here's my codepen so far codepen.io/matttunney/pen/dPMQZL

Thanks

Matt
  • 806
  • 3
  • 12
  • 32

2 Answers2

4

You can use a wrapper around your element, set the width of the wrapper to 100%. and animate it.

This way, the translate is applied to the element width, as you state, but the element width matches the container width

.banner { 
  display:block;
  width:100%;
  height:300px;
  background:#0069aa;
  position:relative;
}
.moveme, .movewidth {
  position:absolute;
}
.movewidth {
  width:100px;
  height:100%;  
  background: #edaf02;
  transform: translate3D(0,0,10px)
}
.wrapper {
  width: 100%;
  animation: moveme 10s linear infinite;
}
.moveme { 
  background:#003356;
  width:100px;
  height:100px;  
  transform: translate3D(0,150px,20px)
}
@keyframes moveme {
  0% { transform: translate(0%, 150px) }
  100% { transform: translate(100%, 100px) }
}

demo

As Simon_Weaver points out, it's confusing to have 2 elements with a 100% width; it's not clear which one is the one proposed as a solution.

A better demo

.banner { 
  display:block;
  width:400px;
  height:300px;
  background:#0069aa;
  position:relative;
}
.moveme, .movewidth {
  position:absolute;
}
.movewidth {
  width:100px;
  height:100%;  
  background: #edaf02;
  transform: translate3D(0,0,10px)
}
.wrapper {
  width: 100%;
  -webkit-animation: moveme 1s linear infinite;
  animation: moveme 1s linear infinite;
}
.moveme { 
  background:#003356;
  width:100px;
  height:100px;  
  transform: translate3D(0,150px,20px)
}
@keyframes moveme {
  0% { transform: translate(0%, 150px) }
  100% { transform: translate(100%, 100px) }
}
@-webkit-keyframes moveme {
  0% { transform: translate(0%, 150px) }
  100% { transform: translate(100%, 100px) }
}
  <div class="banner">
      <div class="movewidth">
      </div>
      <div class="wrapper">
      <div class="moveme">
      </div>
      </div>
    </div>
vals
  • 61,425
  • 11
  • 89
  • 138
0

In the above answer by @vals, it seems that our total window's width is being increased and decreased constantly. Hence I recommend using relative and absolute positioning to the parent and the child elements respectively. And for the animation, we can simply change the position values of the moving container as per the parent's width (removing the usage of translateX()).

pls crct me if wrong