Pesquisa de site

javascript - div de rolagem infinita em CSS


Oi, estou tentando fazer o div rolar com uma animação simples em CSS.

O problema é que ele não faz loop direito, porque há um pequeno flash antes de reiniciar a rolagem.

AQUI ESTÁ O CÓDIGO: https://jsfiddle.net/by6tx4o0/2/

.c{
  position:relative;
  background:red;
  max-height:200px;
  float:left;
  width:300px;
  height:300px;
  overflow:hidden;
  overflow-y:auto;
}
.card-home{
  position:absolute;
  margin:20px;
	top:0;
  	animation: scroll 10s linear 1s infinite;
}
span {
  min-width:300px;
  min-height:40px;
  display:block;
  color:white;
  margin:5px;
  background:blue;
}
@keyframes scroll {
	100% { top: -100%; }
}
<div class="c">sssss
<div class="card-home">
  <span>1</span>
  <span>2</span>
  <span>3</span>
  <span>4</span>
  <span>5</span>
  <span>6</span>
  <span>7</span>
  <span>8</span>
</div>
</div>

O que eu tenho que fazer para que isso fique suave ao repetir?

obrigado

Resposta #1

Hmmm, uma um pouco complicada e vai precisar de alguns valores codificados se você quiser que seja puro CSS, mas aqui está a essência disso:

.c{
  position:relative;
  background:red;
  max-height:225px;  /*height to show an exact number of spans  - in this case span is 45px (40 height plus 5 margin as margins collapse) and we are showing 5 spans to start */
  float:left;
  width:315px;
  height:225px;
  overflow:hidden;
  overflow-y:auto;
}
.card-home{
  position:absolute;
	top:0;
  	animation: scroll 10s linear 1s infinite;
}
span {
  min-width:290px;
  min-height:40px;
  display:block;
  color:white;
  margin:5px;
  background:blue;
}
@keyframes scroll {
	100% { top: -360px; }  /* top is the number of spans (in this case 8) multiplied by span height (45px as described above)*/
}
<div class="c">
<div class="card-home">
  <span>1</span>
  <span>2</span>
  <span>3</span>
  <span>4</span>
  <span>5</span>
  <span>6</span>
  <span>7</span>
  <span>8</span>
  <!-- copy the number of spans displayed at the beggining onto the end -->
  <span>1</span>
  <span>2</span>
  <span>3</span>
  <span>4</span>
  <span>5</span>
</div>
</div>

Também eu sugeriria mover o texto ssss para fora do rolagem para que a margem superior de 20px que você começou não interfira com o rolagem

Resposta #2

Se você quiser que ele role suavemente para o topo assim que a animação estiver completa, uma coisa que você poderia fazer é apenas modificar um pouco sua animação, para que, em vez de terminar na parte inferior, ela termine no topo (esse é o estado original, então não haverá nenhum "salto" quando a animação reiniciar).

Você pode fazer isso por:

  • Rolando até o final usando 95% do tempo da animação.
  • Usando os 5% restantes para rolar para cima.

As mudanças no código seriam realmente simples, e não exigiriam nenhum JavaScript:

@keyframes scroll {
    95% { top: -100%; }
    100% { top:0; }
}

Esta demonstração mostra o resultado:

.c{
  position:relative;
  background:red;
  max-height:200px;
  float:left;
  width:300px;
  height:300px;
  overflow:hidden;
  overflow-y:auto;
}
.card-home{
  position:absolute;
  margin:20px;
  top:0;
  animation: scroll 10s linear 1s infinite;
}
span {
  min-width:300px;
  min-height:40px;
  display:block;
  color:white;
  margin:5px;
  background:blue;
}
@keyframes scroll {
  95% { top: -100%; }
  100% { top:0; }
}
<div class="c">sssss
<div class="card-home">
  <span>1</span>
  <span>2</span>
  <span>3</span>
  <span>4</span>
  <span>5</span>
  <span>6</span>
  <span>7</span>
  <span>8</span>
</div>
</div>