I saw this cool scrolling effect online...
Where the image blends with the next image when scrolling through sections. I\'ve been trying to reproduce it, bu
This can be done using background-attachement:fixed and two similar images.
Here is a simple example:
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;
}
That you can easily scale with many images:
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;
}
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%);
}
Or using 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);
}
For better support, here is a similar idea with some JS to avoid the use of clip-path or mask
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;
}
With many images:
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;
}