skip to Main Content

I’ve created an infinite marquee, but I’m encountering an issue on iOS devices when using Chrome or Safari. After the animation completes, the next frame briefly shows the text at the starting position before restarting the animation. However, this issue does not occur on Android devices or on Chrome’s mobile device emulator in the developer tools on a computer.

How can I modify my code to make it work correctly on iOS devices?

marquee issue

Here is the code I’m using for my infinite marquee

.marquee {
    height: 26px;
    position: relative;
    text-wrap: nowrap;
    max-width: 500px;
    overflow: hidden;
    border: 1px solid black;
}

.marquee-item {
    position: absolute;
    height: 100%;
    left: 100%;
    animation: marquee-animation 5s infinite linear;
}

@keyframes marquee-animation {
    0% {
        left: 100%;
        transform: translateX(0);
        -webkit-transform: translateX(0);
    }

    100% {
        left: 0%;
        transform: translateX(-100%);
        -webkit-transform: translateX(-100%);
    }
}
<div class="marquee">
     <span class="marquee-item">
         Lorem ipsum dolor, sit amet consectetur adipisicing elit.
     </span>
</div>

2

Answers


  1. This isn’t a totally general answer because it deals with the case where the text fits within the min-width given to the parent – i.e. it seems OK for the code as given in the question but may not satisfy your real-use case.

    It scraps positioning in the animation via the left property because that appears to be what causes IOS to have a frame painted (even with opacity 0 which I tested) so causing the flickery effect.

    Instead it uses transforms only – moving the item the sum of its width and the width of the parent.

    <style>
      .marquee {
        height: 26px;
        position: relative;
        text-wrap: nowrap;
        --mW: 500px;
        max-width: var(--mW);
        overflow: hidden;
        border: 1px solid black;
      }
      
      .marquee-item {
        position: absolute;
        height: 100%;
        left: 100%;
        animation: marquee-animation 5s infinite linear forwards;
      }
      
      @keyframes marquee-animation {
        0% {
          transform: translateX(0);
        }
        100% {
          transform: translateX(calc((-1 * var(--mW)) - 100%));
        }
      }
    </style>
    <div class="marquee">
      <span class="marquee-item">
             Lorem ipsum dolor, sit amet consectetur adipisicing elit.
         </span>
    </div>

    Note: I removed the -webkit settings because your code will only work on fairly uptodate versions of IOS anyway – text-wrap was not implemented until version 17.4 (in Safari MacOS as well as IOS).

    Login or Signup to reply.
  2. This is because you are animating left. Apply animation to transform with will-change: transform;, or transform: translate3d(); – it will be smooth.
    Another question is how to make the animated text appear immediately after disappearing.

    .marquee {
      height: 26px;
      text-wrap: nowrap;
      max-width: 500px;
      overflow: hidden;
      border: 1px solid black;
      display: grid;
      align-items: center;
    }
    
    .marquee-item {
      transform: translate3d(100%, 0, 0);
      animation: marquee-animation 5s infinite linear;
    }
    
    @keyframes marquee-animation {
      to {
        transform: translate3d(-100%, 0, 0);
      }
    }
    <div class="marquee">
      <span class="marquee-item">
        Lorem ipsum dolor, sit amet consectetur adipisicing elit.
      </span>
    </div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search