web-dev-qa-db-fra.com

Comment créer un effet de parallaxe sans utiliser une image d'arrière-plan?

J'essaie de créer un effet de parallaxe sans utiliser background-image avec background-attachment: fixed, car background-attachment: fixed ne fonctionne pas aussi bien sur iOS. Voici ce que je suis venu avec:

HTML

<article class="twentyseventeen-panel">
  <div class="panel-image">
    <div style="position: absolute; top: 0; bottom: 0; left: 0; right: 0;" >
      <img src="<?php echo esc_url( $thumbnail[0] ); ?>" style="width: 100%;" />
    </div>
  </div>
</article>

CSS

.twentyseventeen-panel {
    overflow: hidden;
    position: relative;
}
.panel-image {
    position: relative;
    height: 100vh;
    max-height: 200px;
}

Maintenant, je suis bloqué pour arriver à l'image pour faire défiler pour faire l'effet de parallaxe. J'ai essayé de régler l'image sur une position fixed, mais mon image n'apparaît plus lorsque je le fais. Comment puis-je obtenir cette image pour avoir un effet de parallaxe?

17
user979331

Malheureusement, je ne connais aucun moyen sûr d'utiliser du CSS pur. La raison en est qu’il n’ya aucun moyen d’obtenir la position de défilement actuelle (que nous pourrions utiliser dans un calc()). De plus, lors du positionnement d'un élément à l'aide de fixed, il ne se soucie plus de son parent et il devient impossible d'appliquer un overflow:hidden.

Il y a deux façons de créer un effet de paralax sans utiliser d'arrière-plan, soit d'utiliser JavaScript, je vous ai donné un exemple de travail complet. C'est minime, cela pourrait rendre le navigateur trop difficile pour rien, mais cela fonctionne. Vous voudrez certainement l'optimiser pour ne l'appliquer que sur des éléments visibles si vous en avez beaucoup.

$(document).ready(function() {
  var onScroll = function() {
    var scrollTop = $(this).scrollTop();
    $('.paralax-image').each(function(index, elem) {
      var $elem = $(elem);
      $elem.find('img').css('top', scrollTop - $elem.offset().top);
    });
  };
  onScroll.apply(window);
  $(window).on('scroll', onScroll);
});
.content {
  height: 500px;
}

.paralax-image {
  overflow: hidden;
  height: 200px;
  position: relative;
}

.paralax-image img {
  position: absolute;
  height: 100vh;
  min-width:100%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="content">
  <h2>Lorem Ipsum</h2>
  <div class="paralax-image">
    <img src="http://lorempixel.com/400/200">
  </div>


</div>

Maintenant pour la partie CSS complète ... C’est un peu complexe à implémenter et cela ne peut pas être fait pour tout type de mise en page. L'astuce serait d'avoir votre image (s) en utilisant une règle position:fixed. Mais au lieu de s’appuyer sans succès sur overflow:hidden, vous les auriez au plus bas index z, tous vos éléments avec un arrière-plan et créeraient des "trous" à l’affichage. Cela créera beaucoup de problèmes lors de l'ajout d'arrière-plans, vous devrez créer plusieurs éléments différents pour vous assurer que vous avez toujours la possibilité d'afficher l'image paralaxique. J'ai essayé de montrer comment cela pourrait être réalisé sans créer un exemple trop complexe. Cette technique ne fonctionnera que pour 1 image. Si vous voulez que cela fonctionne avec plusieurs images, vous devez utiliser javascript pour changer de visibilité en conséquence, et un seul effet de paralax visible à la fois.

/* Can't use margins no more... */

h1 {
  margin: 0;
  padding: 0.67em 0;
}

p {
  margin: 0;
  padding: 1em 0 0;
}

body {
  margin: 0;
}

.container>* {
  background-color: white;
}

.paralaxed {
  z-index: -2;
  height: 100vh;
  position: fixed;
  top: 0;
}

.paralax-image {
  background: transparent;
  height: 200px;
}
<div class="container">
  <img class="paralaxed" src="http://lorempixel.com/400/200">
  <h1>My Title here</h1>
  <div class="paralax-image"></div>
  <p>
    lorem ipsum...
  </p>
  <p>
    lorem ipsum...
  </p>
  <p>
    lorem ipsum...
  </p>
  <p>
    lorem ipsum...
  </p>
  <p>
    lorem ipsum...
  </p>
</div>

9
Salketer

Vous pouvez réellement créer des effets de parallaxe CSS purs sans avoir besoin de background-image ou background-attachment. Keith Clark a un grand écrire et faire un tutoriel dessus . Je vais emprunter son code pour l'exemple:

HTML

<div class="parallax">
  <div class="parallax__layer parallax__layer--back">
    ...
  </div>
  <div class="parallax__layer parallax__layer--base">
    ...
  </div>
</div>

CSS

.parallax {
  perspective: 1px;
  height: 100vh;
  overflow-x: hidden;
  overflow-y: auto;
}
.parallax__layer {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
}
.parallax__layer--base {
  transform: translateZ(0);
}
.parallax__layer--back {
  transform: translateZ(-1px) scale(2);
}

C'est en fait une solution assez simple, mais il faudra peut-être une seconde pour comprendre comment cela se passe. La grande chose qui se passe ici est la transform: translateZ(-1px) scale(2), qui déplace ce <div> le long de l'axe z et le redimensionne à la normale. Le réglage de l’axe des z détermine comment la vitesse de la parallaxe est contrôlée. Donc, translateZ(-1px) est plus lent que translateZ(-2px).

Maintenant que le div a été déplacé dans l'axe z, il doit être redimensionné à sa taille normale. Pour ce faire, vous ajoutez simplement scale à la propriété transform. L'échelle doit être calculée à l'aide de 1 + (translateZ * -1) / perspective. Donc, transform: translateZ(-10px) devrait être transform: translateZ(-2px) scale(3) en supposant que vous gardiez la valeur perspective définie sur 1px.

Ensuite, la perspective est remplacée par 1px pour le conteneur .parallax, ce qui définira la perspective <div> au centre. L'ajout de overflow-y: auto permet de faire défiler le contenu normalement, mais les éléments descendants seront restitués dans la perspective fixe.

Etant donné que cela utilise uniquement <div>'s et CSS, vous devriez pouvoir résoudre votre problème sans JS. Vous pouvez facilement placer vos images dans les divs. Il s'agit d'une démo simple qui ne montre qu'un seul effet de parallaxe <div>. Si vous examinez le code source, vous ne verrez aucun code JavaScript, à l'exception de la partie destinée à Google Analytics. _ { Voici une démo } _ avec une tonne de sections différentes.

Je vous recommande de lire ce tutoriel _, car le code devrait faire tout ce que vous voulez. De plus, il fonctionne parfaitement sur iOS, Safari, Chrome et FF. Je l'ai utilisé plusieurs fois et je ne saurais trop recommander cette méthode. Inutile de dire que j'ai emprunté une grande partie de ma réponse à ce didacticiel, donc merci à Keith Clark pour la grande rédaction.

4
Matthew Beckman

Pour une raison quelconque, cela semble avoir fonctionné le mieux pour moi:

https://github.com/deggenschwiler/jquery_parallax

Requiert jQuery dans l'en-tête de la page:

<html>
<head>
    <style>
      .parallax {
        height: 400px;
        width: 100%;
        background-image: url("SOMEBGIMAGE.jpg");
        background-position-y: 0%;
        background-repeat: no-repeat;
        background-size: cover;
      }
    </style>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>

    <script>
    $(window).scroll(function() {
          var y = 0;
          var scroll = $(window).scrollTop();
          var win = $(window).height()
          var height = $(".parallax").height();
          var offset = $(".parallax").offset().top;
          y = ((100 * scroll)/(height + win)) + ((100 * (win - offset))/(height + win));
          if (y > 100){y = 100;}
          else if (y < 0){y = 0;}
          var out = String(y) + "%";
          $(".parallax").css("background-position-y", out);
    });
    </script>
</head>
<body>
    <div class="parallax">
    </div>
</body>
</html>
0
Deggen