且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

如何使用CSS创建图像滚动视差效果?

更新时间:2023-10-24 20:11:46

可以使用 background-附件 :fixed 和两个相似的图像。

This can be done using background-attachement:fixed and two similar images.

这里是一个简单示例:

body {
  min-height:200vh;
  margin:0;
  background:url(https://picsum.photos/id/1069/150/150?grayscale) 20px 20px no-repeat;
  background-attachment:fixed;
}

.box {
  margin-top:220px;
  height:200px;
  background:url(https://picsum.photos/id/1069/150/150) 20px 20px no-repeat,
  grey;
  background-attachment:fixed;
}

<div class="box">

</div>

轻松缩放许多图像:

body {
  min-height:250vh;
  margin:0;
  background:url(https://picsum.photos/id/1069/150/150?grayscale) 50px 50px/auto no-repeat;
  background-attachment:fixed;
}

.box {
  height:200px;
  background:url(https://picsum.photos/id/1069/150/150) 50px 50px/auto no-repeat,
  grey;
  background-attachment:fixed;
}
.box:first-child {
  margin-top:200px;
}

<div class="box">
</div>
<div class="box" style="background-image:url(https://picsum.photos/id/11/150/150);background-color:yellow">
</div>
<div class="box" style="background-image:url(https://picsum.photos/id/106/150/150);background-color:pink">
</div>

您还可以考虑使用 img position:fixed ,但是您将需要一些技巧使用剪切路径

You can also consider the use of img and position:fixed but you will need some trick to hide the overflow using clip-path

body {
  min-height: 250vh;
  margin: 0;
  padding-top: 100px;
}

img {
  position: fixed;
  top: 50px;
  left: 50px;
}

.box {
  height: 200px;
  background: grey;
  clip-path:polygon(0 0,100% 0,100% 100%,0 100%);
}

<div class="box">
  <img src="https://picsum.photos/id/1074/200/120?grayscale">
</div>
<div class="box" style="background-color:red;">
  <img src="https://picsum.photos/id/1074/200/120">
</div>
<div class="box" style="background-color:yellow;">
  <img  src="https://picsum.photos/id/1024/200/120?grayscale">
</div>
<div class="box" style="background-color:pink;">
  <img src="https://picsum.photos/id/1024/200/120">
</div>

或使用 mask

body {
  min-height: 250vh;
  margin: 0;
  padding-top: 100px;
}

img {
  position: fixed;
  top: 50px;
  left: 50px;
}

.box {
  height: 200px;
  background: grey;
  -webkit-mask:linear-gradient(#fff,#fff);
          mask:linear-gradient(#fff,#fff);
}

<div class="box">
  <img src="https://picsum.photos/id/1074/200/120?grayscale">
</div>
<div class="box" style="background-color:red;">
  <img src="https://picsum.photos/id/1074/200/120">
</div>
<div class="box" style="background-color:yellow;">
  <img  src="https://picsum.photos/id/1024/200/120?grayscale">
</div>
<div class="box" style="background-color:pink;">
  <img src="https://picsum.photos/id/1024/200/120">
</div>


为了获得更好的支持,有些JS的想法与此类似,以避免使用剪切路径或蒙版

For better support, here is a similar idea with some JS to avoid the use of clip-path or mask

我将使用CSS变量更新图像的位置,但您可以轻松地做到以下几点:

I will update the position of the image using a CSS variables but you can easily do without:

window.onscroll = function() {
  var scroll = window.scrollY || window.scrollTop || document.getElementsByTagName("html")[0].scrollTop;
  document.documentElement.style.setProperty('--scroll-var', scroll+"px");
}

:root {
  --scroll-var: 0px;
}

body {
  min-height: 150vh;
  margin: 0;
}

img {
  position: fixed;
  top: 20px;
  left: 20px;
}

.box {
  margin-top: 220px;
  height: 200px;
  background: grey;
  position: relative;
  overflow: hidden;
}

.box img {
  top: calc(-220px + 20px + var(--scroll-var));
  /* margin of box + top of the other image + scroll*/
  position: absolute;
}

<img src="https://picsum.photos/id/1069/150/150?grayscale">
<div class="box">
  <img src="https://picsum.photos/id/1069/150/150">
</div>

具有很多图像:

window.onscroll = function() {
  var scroll = window.scrollY || window.scrollTop || document.getElementsByTagName("html")[0].scrollTop;
  document.documentElement.style.setProperty('--scroll-var', scroll+"px");
}

:root {
  --scroll-var: 0px;
}

body {
  min-height: 250vh;
  margin: 0;
  padding-top:200px;
}

img {
  position: fixed;
  top: 50px;
  left: 50px;
}

.box {
  height: 200px;
  background: grey;
  position: relative;
  overflow: hidden;
}
img.f1 {
  top: calc(-200px + 50px + var(--scroll-var));
  position: absolute;
}
img.f2 {
  top: calc(-400px + 50px + var(--scroll-var));
  position: absolute;
}
img.f3 {
  top: calc(-600px + 50px + var(--scroll-var));
  position: absolute;
}

<img src="https://picsum.photos/id/1069/100/100?grayscale">
<div class="box">
  <img class="f1" src="https://picsum.photos/id/1069/100/100">
</div>
<div class="box" style="background-color:yellow;">
  <img class="f2" src="https://picsum.photos/id/107/100/100">
</div>
<div class="box" style="background-color:pink;">
  <img class="f3" src="https://picsum.photos/id/1072/100/100">
</div>