Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CSS scroll animation restarts before all text has scrolled

I'm trying to make a list of 100 paragraphs repeatedly scroll up, but the animation is restarting before the list finishes scrolling, at about 48 paragraphs. How can I make sure that all paragraphs scroll before the animation restarts?

div = document.getElementById("titlecontent");
for (c = 0; c < 100; c++) {
  str = c;
  p = document.createElement("p");
  p.innerText = str;
  div.appendChild(p);
}
p = document.createElement("p");
p.innerText = "last p reached";
div.appendChild(p);
#titlecontent {
  position: absolute;
  top: 100%;
  -webkit-animation: scroll 10s linear 0s infinite;
  -moz-animation: scroll 10s linear 0s infinite;
  -ms-animation: scroll 10s linear 0s infinite;
  -o-animation: scroll 10s linear 0s infinite;
  animation: scroll 10s linear 0s infinite;
}

@-webkit-keyframes scroll {
  0% { top: 100%; }
  100% { top: -170%; }
}
@-moz-keyframes scroll {
  0% { top: 100%; }
  100% { top: -170%; }
}
@-ms-keyframes scroll {
  0% { top: 100%; }
  100% { top: -170%; }
}
@-o-keyframes scroll {
  0% { top: 100%; }
  100% { top: -170%; }
}
@keyframes scroll {
  0% { top: 100%; }
  100% { top: -170%; }
}
<div id="titlecontent"></div>
like image 240
sigil Avatar asked Dec 01 '16 08:12

sigil


1 Answers

Your problem lies with top/bottom being related to the height of the screen, since the div is longer than those dimensions, it won't work.

I think I found a good solution, using only CSS.

Animating the top/bottom values is impossible, since CSS animations require their exact counterpart to animate, however, there is a property we can use to animate based on the entire height of the element

Introducing: CSS Transforms (translateX).

div = document.getElementById("titlecontent");
for (c = 0; c < 100; c++) {
  str = c;
  p = document.createElement("p");
  p.innerText = str;
  div.appendChild(p);
}
p = document.createElement("p");
p.innerText = "last p reached";
div.appendChild(p);
body {
    overflow: hidden;
}

body {
    overflow: hidden;
}

#titlecontent {
  animation: scroll 20s linear 0s infinite;
}

@-webkit-keyframes scroll {
  0% { transform: translateY(10%); }
  100% { transform: translateY(-100%); }
}
<div id="titlecontent"></div>

The magic happens in these lines:

  0% { transform: translateY(10%); }
  100% { transform: translateY(-100%); }

Instead of animating offset, we're animating the element's position on the X axis of the screen. Making it -100% of it's actual height, and then animating it to 100% of it's actual height, effectively animating it offscreen before it repeats.

You just need to decide where the scrolling up should start, in this example 10%

like image 107
roberrrt-s Avatar answered Oct 14 '22 06:10

roberrrt-s