Search code examples
cssanimationtransformtranslate-animation

Animate a object across the width of its parent using css transforms


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


Solution

  • 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>