如何在不使用背景图像的情况下创建视差效果?

问题描述 投票:0回答:5

我试图在不使用

background-image
background-attachment: fixed
的情况下创建视差效果,因为
background-attachment: fixed
在 iOS 上效果不太好。这是我想到的:

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;
}

现在我坚持滚动图像以实现视差效果。我尝试将图像设置为

fixed
位置,但是当我这样做时,我的图像不再出现。如何让该图像具有视差效果?

html css parallax
5个回答
16
投票

不幸的是,我不知道有什么可靠的使用纯 CSS 的方法。原因是无法获取当前滚动位置(我们可以在

calc()
中使用)。此外,当使用
fixed
定位元素时,它不再关心其父元素,并且不可能强制执行
overflow:hidden

有两种方法可以在不使用背景的情况下创建视差效果,一种是使用 JavaScript,我已经给了您一个完整的工作示例。它很小,可能会让浏览器毫无意义地工作太多,但它确实有效。如果您有很多元素,您肯定会希望将其优化为仅应用于可见元素。

$(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="https://via.placeholder.com/400x200">
  </div>


</div>

现在是完整的 CSS 部分...实现起来有点复杂,并且无法针对每种布局完成。诀窍是让你的图像使用

position:fixed
规则。但是,您不会成功地依赖
overflow:hidden
,而是将它们置于最低的 z-index,让所有元素都带有背景,并在要显示图像的位置创建“孔”。添加背景时这会产生很多问题,您必须制作多个不同的元素以确保始终可以显示视差图像。我试图演示如何实现这一点,而无需创建过于复杂的示例。此技术仅适用于 1 个图像。如果你想让它处理多个图像,你必须使用 javascript 来相应地切换可见性,并且一次只能看到 1 个视差效果。

/* 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="https://via.placeholder.com/400x200">
  <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>


11
投票

您实际上可以制作纯 CSS 视差效果,而不需要

background-image
background-attachment
。 Keith Clark 有一篇很棒的关于它的文章和教程。为了示例,我将借用他的代码:

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);
}

这实际上是一个非常简单的解决方案,但可能需要一些时间才能了解这一切是如何发生的。这里发生的最重要的事情是

transform: translateZ(-1px) scale(2)
,它将
<div>
沿着 z 轴向后移动,并将其大小调整回正常状态。设置 z 轴是控制视差速度的方式。所以
translateZ(-1px)
translateZ(-2px)
慢。

现在 div 已在 z 轴上移回,需要将其大小调整回正常大小。为此,您只需将

scale
添加到
transform
属性即可。比例必须使用
1 + (translateZ * -1) / perspective
计算。因此,假设您将
transform: translateZ(-10px)
设置为
transform: translateZ(-2px) scale(3)
perspective
应该是
1px

然后将

perspective
容器的
1px
更改为
.parallax
,这会将
<div>
透视设置为中心。添加
overflow-y: auto
允许内容正常滚动,但后代元素将渲染到固定视角。

由于这仅使用

<div>
CSS,因此您应该能够在没有JS的情况下解决您的问题。您可以轻松地将图像放置在 div 中。这是一个简单的演示,仅显示单个
<div>
视差效果。如果您查看源代码,您将看到除了 Google Analytics 部分之外没有任何 JavaScript。 这是一个演示,其中包含大量不同的部分。

我建议您阅读本教程,因为代码应该可以完成您想要的一切。另外,它可以在 iOS、Safari、Chrome 和 FF 上完美运行。我已经使用过很多次了,我强烈推荐这个方法。不用说,我从该教程中借用了大部分答案,因此感谢 Keith Clark 的精彩写作。


0
投票

无论出于何种原因,这似乎对我来说效果最好:

https://github.com/deggenschwiler/jquery_parallax

页面标题中需要 jQuery:

<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
投票

纯 CSS 解决方法:将容器填充设置为视差高度(例如 100vh),然后将子项(视差区域)固定/绝对放置在其中。使用 z-index 来实现视差滚动效果。为我工作:)


0
投票

我知道这是一个相当老的问题,但现在有一个解决方案,所以我决定将其放在这里,供仍在寻找它的人使用。 css 中有一个名为

scroll()
的函数,尽管目前并非所有浏览器都支持它(您应该在here查看它),它允许您根据滚动条轴控制动画时间线。所以你可以做出这样的视差效果:

body {
        display: flex;
        justify-content: center;
        align-items: center;
        min-height: 200dvh;
    }

    .container {
        width: 200px;
        height: 200px;
        overflow: hidden;
        display: flex;
    }

    img {
        object-fit: cover;
        animation-name: img-up-down;
        animation-duration: 1ms;
        animation-direction: alternate;
        animation-timing-function: linear;
        animation-timeline: scroll(root);
        min-width: 100%;
    }

    @keyframes img-up-down {
        0% {
            object-position: top;
        }

        100% {
            object-position: bottom;
        }
    }
<body>
    <div class="container">
        <img src="https://images.squarespace-cdn.com/content/v1/52540926e4b0d49865bee20d/1473520260750-LO9DJ4REDZYHU25BDX25/London+portrait+photographer"
            alt="">
    </div>
</body>

© www.soinside.com 2019 - 2024. All rights reserved.