web-dev-qa-db-fra.com

Manière CSS de boucler une image d'arrière-plan avec une couverture ou contenant un dimensionnement

Supposons que vous essayez d'animer un arrière-plan en mosaïque comme celui-ci:

.container {
  width: 160px;
  height: 91px;
}
.bg {
  width: 100%;
  height: 100%;
  background: url(http://i60.tinypic.com/2j2fhjm.jpg) repeat-x left center;
  background-size: contain;
  -webkit-animation: displace 2s linear infinite;
  animation: displace 2s linear infinite;
}
@-webkit-keyframes displace {
  from {
    background-position: 0 center;
  }
  to {
    background-position: 160px center;
  }
}
@keyframes displace {
  from {
    background-position: 0 center;
  }
  to {
    background-position: 160px center;
  }
}
<div class="container">
  <textarea class="bg"></textarea>
</div>

Dès que vous modifiez les dimensions du conteneur, l'animation de boucle se rompt!

Existe-t-il un moyen de rendre cela réactif sans JS?

33
Vandervals

Le problème est que, pour le rendre réactif, vous devez définir la position d'arrière-plan animée à l'aide de pourcentages.

Mais, lorsque vous définissez la taille d'arrière-plan comme couverture ou contenant, dans certains cas, la largeur est ajustée à 100%. Dans ce cas, la position d'arrière-plan utilisant des pourcentages est inutile (ne la déplace pas).

Le seul moyen que j'ai trouvé pour gérer cela est de déplacer l'image vers un pseudo-élément et de la déplacer. Pour garder la continuité, cependant, nous aurons besoin de deux pseudo-éléments.

Mais cela ne fonctionnera pas sur une zone de texte.

Vous n'avez rien dit au sujet de la textarea étant une exigence, donc je poste ceci. Pour montrer qu'il fonctionne sur le redimensionnement, survolez-le.

.container {
  width: 160px;
  height: 100px;
  position: relative;
  border: solid 1px black;
  display: inline-block;
}
.container:nth-child(2) {
   width: 220px;  
}
.bg {
    position: absolute;
    width: 100%;
    height: 100%;
    overflow: hidden;
}

.bg:before, .bg:after {
    content: "";
    position: absolute;
    width: 100%;
    height: 100%;
    background-image: url(http://i.stack.imgur.com/wBHey.png);
    background-size: 100%;
    animation: move 2s infinite linear;
}

.bg:before {
    right: 100%;
}

@keyframes move {
    from {transform: translateX(  0%);}
      to {transform: translateX(100%);}
}
<div class="container">
  <div class="bg"></div>
</div>
<div class="container">
  <div class="bg"></div>
</div>

test image

26
vals

J'ai pu le faire fonctionner en rendant l'arrière-plan deux fois plus grand.

Je sais que ce n'est pas la solution parfaite, mais vous pouvez peut-être faire un tour avec la taille de l'image ou quelque chose pour lui donner l'apparence que vous vouliez.

    .container {width: 160px;height: 91px;}
    .bg {
      width: 100%;
      height: 100%;
      background: url(http://i60.tinypic.com/2j2fhjm.jpg) repeat-x left center;
      background-size: 200%;
      -webkit-animation: displace 2s linear infinite;
      animation: displace 2s linear infinite;
    }
    @-webkit-keyframes displace {
      from { background-position: left center;
      } to { background-position: 200% center; }
    }
    @keyframes displace {
      from { background-position: left center;
      } to { background-position: 200% center; }
    }
<div class="container"><textarea class="bg"></textarea></div>
11
Okku

Le problème que vous rencontrez concerne le redimensionnement height et vos différents paramètres. Pour le faire fonctionner avec vos paramètres réels, le déplacement devrait être 2x le height de l'image (puisque l'image a une ration de 2: 1). Je ne pense pas que vous pouvez le faire uniquement par css.

Mais vous avez différentes options. Je ne sais pas exactement quelle partie de vous afficher vous souhaitez conserver, alors voici trois façons de faire fonctionner votre traduction sur resize. Aucun n'a exactement vos paramètres, car ceux que vous avez rendent difficile (impossible?) De définir le bon déplacement. Puisque vous étirez la largeur en fonction de la hauteur, il est difficile de suivre. Via JS, ce serait facile, mais css a un accès limité à ces valeurs.

Les solutions proposées maintiennent la hauteur constante afin que vous puissiez garder votre valeur de déplacement constante.

Tout d'abord, la taille de l'arrière-plan est la taille du conteneur en px.

Deuxième solution, vous redimensionnez la zone de texte uniquement sur l'axe des x.

Troisièmement, vous répétez sur l'axe y et maintenez la hauteur et la largeur fixes.

Il existe probablement d'autres solutions de contournement qui sont peut-être plus adaptées à vos besoins spécifiques.

.container {
  width: 160px;
  height: 80px;
   margin: 10px;
}

.bg {
  width: 100%;
  height: 100%;
  background: url(http://i60.tinypic.com/2j2fhjm.jpg) repeat-x left center;
  background-size: 160px 80px;
     padding: 0px;
  -webkit-animation: displace 2s linear infinite;
  animation: displace 2s linear infinite;
}
.bg2 {
  width: 100%;
  height: 100%;
  background: url(http://i60.tinypic.com/2j2fhjm.jpg) repeat-x left center;
  background-size: contain;
     padding: 0px;
    resize: horizontal;
  -webkit-animation: displace 2s linear infinite;
  animation: displace 2s linear infinite;
}
.bg3 {
  width: 100%;
  height: 100%;
  background: url(http://i60.tinypic.com/2j2fhjm.jpg) repeat left center;
  background-size: 160px 80px;
     padding: 0px;
  -webkit-animation: displace 2s linear infinite;
  animation: displace 2s linear infinite;
}

@-webkit-keyframes displace {
  from {
    background-position: 0 center;
  }
  to {
    background-position: 160px center;
  }
}
@-keyframes displace {
  from {
    background-position: 0 center;
  }
  to {
    background-position: 160px center;
  }
}
<div class="container">
  <textarea class="bg"></textarea>
</div>
<div class="container">
  <textarea class="bg2"></textarea>
</div>
<div class="container">
  <textarea class="bg3"></textarea>
</div>
3
Julien Grégoire

Pour chaque background-position: 200px bottom; vous devez ajouter 1second par exemple si vous voulez ajouter 2S, vous ajoutez 200px supplémentaires pour que vous le fassiez background-position: 400px bottom; Je pense.

Voici le code:

.container {
  width: 160px;
  height: 91px;
}

.bg {
 width: 100%;
  height: 100%;
  background: url(http://i60.tinypic.com/2j2fhjm.jpg) fixed;
  -webkit-animation: displace 1s linear infinite;
  animation: displace 1s linear infinite;
}

@-webkit-keyframes displace {
  from { background-position: 0 bottom; }
  to { background-position: 200px bottom; }
}

@keyframes displace {
  from { background-position: 0 bottom; }
  to { background-position: 200px bottom;}
}
<div class="container">
  <textarea class="bg"></textarea>
</div>

J'espère que cela fonctionne pour votre cas, faites-moi savoir si vous avez des questions.

2
Mohammed Moustafa

Ceci est similaire à la réponse d'Ilpo, sauf qu'il ne redimensionne pas l'image (background-size: auto;). L'animation est fluide tout au long, quelle que soit la taille du conteneur.

L'inconvénient est que la largeur (200px) de l'image doit être connue à l'avance.

Puisque vous avez dit carrelable, et puisque cette image semble pouvoir être carrelée dans les deux directions, je l'ai également fait répéter dans les deux dimensions. Par conséquent, votre textarea est remplie avec l'image d'arrière-plan en mosaïque, animée pour défiler horizontalement. Si vous ne souhaitez créer une mosaïque que dans une direction, vous pouvez remplacer repeat par repeat-x et changez la position verticale de top en celle dont vous avez besoin.

.container {width: 160px;height: 91px;}

.bg {
  width: 100%;
  height: 100%;
  background: url(http://i60.tinypic.com/2j2fhjm.jpg) repeat left top;
  background-size: auto;
  -webkit-animation: displace 2s linear infinite;
  animation: displace 2s linear infinite;
}

@-webkit-keyframes displace {
  from { background-position: 0px top; }
  to   { background-position: 200px top; }
}

@keyframes displace {
  from { background-position: 0px top; }
  to   { background-position: 200px top; }
}
<div class="container"><textarea class="bg"></textarea></div>
2
tavnab
.container {
  border: 1px solid black;
  display: inline-block;
  background: url(http://i60.tinypic.com/2j2fhjm.jpg) repeat-x left center;
  -webkit-animation: displace 2s linear infinite;
  animation: displace 2s linear infinite;
  background-size: 160px 100%;
}

.bg {
  float: left;
  border: 0;
  margin: 10px;
  width: 160px;
  height: 91px;
  background-color: rgba(255, 255, 255, .5);
}

@-webkit-keyframes displace {

  from {
    background-position: 0 center;
  }

  to {
    background-position: 160px center;
  }

}

@keyframes displace {

  from {
    background-position: 0 center;
  }

  to {
    background-position: 160px center;
  }

}
<div class="container">
  <textarea class="bg"></textarea>
</div>
1
wolfhammer