Round play is a common way to display multiple images and words. There are many types, such as discrete periodic play and continuous infinite play.

There are many libraries that encapsulate this component, and these libraries are very powerful and can be adapted to many scenarios. However, if you understand the principle of round casting, you can use CSS to implement it, which is very helpful for business to cope with changing requirements.

In this article, I’d like to share with you the next method for implementing infinite round casting using pure CSS.

scenario

For example, there is now a requirement to display announcements in horizontally moving text, one after the other, the first after the last, in an infinite loop.

First look at the effect:

Or click to see an example web page

methods

The container

First we create the container:

<style>
  #wrap {
    overflow: hidden;
    width: 600px;
    white-space: nowrap;
  }
</style>

<div id="wrap"></div>
Copy the code

With a container of limited width and a div to hide the overflow content, set white-space: Norwap to keep the text verbatim.

The text

Add text:

<div id="wrap">
  <div id="slide">The story of the little yellow flower from the birth of the year has been floating childhood swing with memory has been swaying to the present Re So So Si Do Si La So La Si Si Si Si Si Si La So</div>
</div>
Copy the code

Where # Slide is the text that needs to be moved.

animation

To animate the text, set the animation property:

<style>
  #slide {
    animation: slide 10s linear infinite;
  }

  @keyframes slide {
    0% {
      transform: translateX(0);
    }
    100% {
      transform: translateX(-100%); }}</style>
Copy the code

In the case that the length of the text is uncertain, let’s assume the move is -100%.

The effect is as follows:

There are two problems:

  1. The distance moved is not the length of the text
  2. There is no beginning or end to the text

Mobile distance

The reason for the first problem is that Transform: translateX’s percentage of movement is self-referential, but since #slide is a block-level element in the document flow, its width defaults to the parent element’s width. So text moves only by the width of the parent element, not by the length of the text itself.

To fix this, take # Slide out of the flow of the document so that the text is stretched wide, and use the position: Absolute method. Example:

<style>
  #wrap {
    overflow: hidden;
    position: relative;
    width: 600px;
    height: 20px;
    white-space: nowrap;
  }
  #slide {
    position: absolute;
    animation: slide 10s linear infinite;
  }
</style>
Copy the code

The effect is as follows:

End to end

Let’s look at the second question. Imagine that for a piece of text, it’s impossible to go end to end unless there’s a wormhole. What if there were two identical paragraphs of text?

The end of the first paragraph of text is linked to the beginning of the second paragraph. Because the content on both sides of the text is the same, it is visually like the end of the text. However, at the end of the second paragraph of text, there will be a problem that the end is not connected. We cannot add the same text indefinitely to achieve the effect.

We know that by default the animation is mutated after completion, that is, the element position mutates to the original position after completion (as shown in the figure above). The text moves to the last section, leaves a blank space, and then suddenly returns to the beginning. We can take this mutation and figure out how to make the visual effect consistent before and after the mutation.

We now have two pieces of the same text, and imagine that we don’t need both pieces of text to play through. By the time the first text is played, it has moved 50% of the distance and is now connected to the head of the second text. If the animation jumps to the start position, the first paragraph of the text replaces the first paragraph of the second paragraph, and the animation returns to the start position. Visually, we don’t feel this shift in position, because the two paragraphs of text are identical.

The implementation code is as follows:

<style>@keyframes slide { 0% { transform: translateX(0); } 100% { transform: translateX(-50%); }}<div id="slide">
    <span>The story of the little yellow flower from the birth of the year has been floating childhood swing with memory has been swaying to the present Re So So Si Do Si La So La Si Si Si Si Si Si La So</span>
    <span>The story of the little yellow flower from the birth of the year has been floating childhood swing with memory has been swaying to the present Re So So Si Do Si La So La Si Si Si Si Si Si La So</span>
  </div>
Copy the code

We set the movement distance of the animation to -50% and arrange two identical pieces of text at the same time. When the text moves half the distance of two pieces of text (that is, the distance of one piece of text), the animation restarts, mutates to the starting position, and visually the text does not move, giving an end-to-end effect.

By extension, the same is true for infinite rounds of images. Just add an element after the last image that is identical to the first image.

conclusion

The main points of infinite rotation are as follows:

  1. Two identical paragraphs of text
  2. I’m going to go 50% of the way

The Demo code is as follows:

<! DOCTYPEhtml>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="Width = device - width, initial - scale = 1.0" />
    <title>Infinite round of text</title>

    <style>
      body {
        display: flex;
        justify-content: center;
        align-items: center;
        height: 100vh;
      }

      #wrap {
        overflow: hidden;
        position: relative;
        width: 600px;
        height: 20px;
        padding-bottom: 5px;
        border-bottom: 1px solid #cccccc;
        white-space: nowrap;
      }

      #slide {
        position: absolute;
        animation: slide 10s linear infinite;
      }

      @keyframes slide {
        0% {
          transform: translateX(0);
        }
        100% {
          transform: translateX(-50%); }}</style>
  </head>
  <body>
    <div id="wrap">
      <div id="slide">
        <span>The story of the little yellow flower from the birth of the year has been floating childhood swing with memory has been swaying to the present Re So So Si Do Si La So La Si Si Si Si Si Si La So</span>
        <span>The story of the little yellow flower from the birth of the year has been floating childhood swing with memory has been swaying to the present Re So So Si Do Si La So La Si Si Si Si Si Si La So</span>
      </div>
    </div>
  </body>
</html>
Copy the code