skip to Main Content

I’m animating a background gradient by moving the background-position via animation. However, the transition from the end of the animation to the start of the next cycle isn’t smooth. It should appear as if it’s on a continuous loop. What am I missing?

CodePen

.gradient {
  width: 200px;
  height: 30px;
  background-image: linear-gradient(
      to right,
      red 8.33%,
      #ff9900 16.67%,
      yellow 25%,
      red 41.67%,
      #ff9900 58.34%,
      yellow 75.01%,
      red 83.34%
    );
    -webkit-animation: flow 3s ease infinite;
    -o-animation: flow 3s ease infinite;
    -ms-animation: flow 3s ease infinite;
    -moz-animation: flow 3s ease infinite;
    animation: flow 3s ease infinite;
    -webkit-animation: flow 3s ease infinite;
    background-size: 400% 100%;
    overflow: hidden;
}

@-webkit-keyframes flow {
    0% {
      background-position: -100% 50%;
    }
    100% {
      background-position: 100% 50%;
    }
  }

  @keyframes flow {
    0% {
      background-position: -100% 50%;
    }
    100% {
      background-position: 100% 50%;
    }
  }
<div class="gradient" />

2

Answers


  1. You have set the width to 400% but you are only moving the background by a total of 200%.

    Try making them match. This snippet just sets the keyframe translation to -400%.

    .gradient {
      width: 200px;
      height: 30px;
      background-image: linear-gradient( to right, red 8.33%, #ff9900 16.67%, yellow 25%, red 41.67%, #ff9900 58.34%, yellow 75.01%, red 83.34%);
      -webkit-animation: flow 3s ease infinite;
      -o-animation: flow 3s ease infinite;
      -ms-animation: flow 3s ease infinite;
      -moz-animation: flow 3s ease infinite;
      animation: flow 3s ease infinite;
      -webkit-animation: flow 3s ease infinite;
      background-size: 400% 100%;
      overflow: hidden;
    }
    
    @-webkit-keyframes flow {
      0% {
        background-position: -400% 50%;
      }
      100% {
        background-position: 0% 50%;
      }
    }
    
    @keyframes flow {
      0% {
        background-position: -400% 50%;
      }
      100% {
        background-position: 0% 50%;
      }
    }
    <div class="gradient" />

    There is of course the question of whether you really want that stop-start effect brought on by the ease function – maybe you do but if not look at using linear.

    Login or Signup to reply.
  2. I would first simplify your gradient using a repeating one since you are repeating some of the colors then the correct formula to update the position and have a cycle is (s/(s-1))*100% where s is the size factor.

    In your case, s = 4 because you are using 400% so you need to move by 400%/3

    .gradient {
      width: 200px;
      height: 30px;
      background-image: repeating-linear-gradient(90deg,red,#ff9900 12.5%,yellow 25%,red 50%);
      background-size: 400% 100%;
      animation: flow 2s linear infinite;
    }
    
      @keyframes flow {
        100% {
          background-position: calc(400%/3);
        }
      }
    <div class="gradient" ></div>

    Related to get more detail about the calculation: Using percentage values with background-position on a linear-gradient

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search