Reputation: 11
So, I'm trying to figure out a cool/different way to show full web designs that differs from long static images. My goal is to have a "monitor" graphic stick while an image (full web page) flows inside it as the user scrolls. I sorta solved it by having a position sticky "monitor" graphic with an image flowing under it. I love how it scrolls though the content then pushes the section up after it finishes.
The problem is with the image overflow. I was able to hide the overflow on the top with a border (which i think will work fine in the long run).. but I can't figure out how to hide the overflow at the bottom and still keep the same scrolling behavior it has now.
It would be great to also somehow get rid of the space at the bottom of the "monitor" so it sits right at the bottom of the container. I suppose the functionality would ultimately be like a sticky iframe that can be scrolled outside the frame itself and would then push up after the content reaches its end.
I was able to this far, but really having an issue hiding the overflow at the bottom of the div while still maintaining the scroll behavior.
EXAMPLE >> https://codepen.io/cjcort/pen/NWKryVa
Thanks in advance!
<style>
body {
margin:0px;
}
.container-1 {
background-color:grey;
}
.container-2 {
background-color:lightblue;
}
.parent {
width:50%;
margin:0px auto;
padding:100px 0px;
}
.sticky-monitor {
text-align: center;
z-index:1
}
.grey {
border-top:70px grey solid;
}
.blue{
border-top:70px lightblue solid;
}
.sticky-monitor img {
width:100%;
left:0;
right:0;
margin-left:auto;
margin-right:auto;
z-index:4
}
.image {
margin-top:-65%;
text-align:center;
}
.image img {
width:93%;
height:1000px !important;
margin:auto
}
.is-sticky {
position: sticky;
position: -webkit-sticky;
position: -moz-sticky;
position: -ms-sticky;
position: -o-sticky;
top: 0;
}
</style>
<div class="container-1">
<div class="parent">
<div class="sticky-monitor is-sticky grey">
<img src="https://charliecort.com/test/computer.svg">
</div>
<div class="image">
<img src="https://images.unsplash.com/photo-1563468415006-0b70ca8eb306?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=934&q=80" />
</div>
</div>
</div>
<div class="container-1">
<div class="parent">
<div class="sticky-monitor is-sticky grey">
<img src="https://charliecort.com/test/computer.svg">
</div>
<div class="image">
<img src="https://images.unsplash.com/photo-1563468415006-0b70ca8eb306?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=934&q=80" />
</div>
</div>
</div>
Upvotes: 0
Views: 5863
Reputation: 5411
Unfortunately, using overflow: hidden
and position: sticky
ruins the sticky effect.
Dealing with overflow and position: sticky
It greatly limits CSS solutions. For now, I can only think in a JavaScript one.
You can calculate the height of the container space below the monitor. This height will be used in a element to hide the escaping image part.
First, create an div in sticky-monitor
. Let's set .hide-image
class to it:
<div class="sticky-monitor is-sticky grey">
<img src="http://charliecort.com/test/computer.svg">
<div class="hide-image"></div>
</div>
CSS:
.hide-image {
position: absolute;
width: 100%;
background: grey;
transform: translateY(-4px); // to fill the small gap
}
Finally, the JavaSript for the height calculation. There will be a base calculation variable whose values will be recalculated only when the window resizes, since during scroll they don't change. The height will be calculated whenever scroll happens:
// variables to get elements;
var container = document.querySelector('.container');
var monitor = document.querySelector('.container .sticky-monitor');
var hideImageElement = document.querySelector('.hide-image');
// variable for calculation later
var baseForCalc;
window.addEventListener('resize', getValuesImage);
window.addEventListener('scroll', adjustHideImage);
function getValuesImage() {
baseForCalc = container.offsetHeight + container.offsetTop - monitor.offsetHeight;
adjustHideImage();
}
function adjustHideImage () {
hideImageElement.style.height = (baseForCalc - monitor.offsetTop) + 'px';
}
getValuesImage(); // get the values at least once
adjustHideImage(); // apply the values at least once
Upvotes: 1