Reputation: 233
I have a scenario where I need overflow auto for the scrollbar but I want one of the elements inside to pop out. I made a demo which shows what I'm currently getting. I would like that blue box to not cut behind while still having overflow auto on my main container.
I could only get it to kind of work by making the blue box position: fixed
but that way I'm unable to align it besides my red div.
How should this be done?
html,
body {
padding: 0;
margin: 25px 0;
font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, Ubuntu, Cantarell, Fira Sans, Droid Sans,
Helvetica Neue, sans-serif;
text-align: center;
background: #091c32;
color: #fff;
}
.scroll {
border: 5px solid #000;
padding: 0 10px;
max-width: 250px;
margin: 0 auto;
max-height: 400px;
overflow: auto;
}
.box {
position: relative;
width: 100%;
height: 205px;
border: 2px solid #000;
background: red;
margin: 10px 0;
}
.innerBox {
position: absolute;
width: 150px;
height: 50px;
border: 2px solid #fff;
background: blue;
top: 0;
left: 0;
transform: translate(-50%, -50%);
z-index: 1000;
}
<div class="scroll">
<div class="box">
<div class="innerBox">Hello</div>
</div>
<div class="box">
<div class="innerBox">World</div>
</div>
</div>
EDIT:
After applying the css trick @chazsolo suggested, I discovered that I still have an issue of the blue box not following the red boxes on scroll.
But furthermore it made me realize that there's even a bigger issue to fix; which is being able to hide those blue boxes that are underneath the .scroll
div.
Here's updated code:
html,
body {
padding: 0;
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, Ubuntu, Cantarell, Fira Sans, Droid Sans,
Helvetica Neue, sans-serif;
text-align: center;
background: #091c32;
color: #fff;
}
a {
color: inherit;
text-decoration: none;
}
* {
box-sizing: border-box;
}
.scroll {
border: 5px solid #000;
padding: 0 10px;
max-width: 250px;
margin: 0 auto;
max-height: 400px;
overflow: auto;
}
.box {
position: relative;
width: 100%;
height: 205px;
border: 2px solid #000;
background: red;
margin: 10px 0;
position: static;
}
.innerBox {
position: absolute;
width: 150px;
height: 50px;
border: 2px solid #fff;
background: blue;
// top: 0;
// left: 0;
transform: translate(-50%, -50%);
}
<div class="scroll">
<div class="box">
<div class="innerBox">Hello</div>
</div>
<div class="box">
<div class="innerBox">World</div>
</div>
<div class="box">
<div class="innerBox">Hello</div>
</div>
<div class="box">
<div class="innerBox">World</div>
</div>
</div>
Upvotes: 2
Views: 164
Reputation: 233
Here's a useable solution to this, if it's ever needed.
const scrollBox = document.querySelector('.scroll');
const boxes = document.querySelectorAll('.innerBox');
scrollBox.addEventListener('scroll', e => {
boxes.forEach(box => {
const top = box.parentElement.offsetTop;
const bHH = box.offsetHeight / 2;
box.style.top = `${top - e.target.scrollTop + bHH}px`;
});
});
html,
body {
padding: 0 25px;
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
text-align: center;
background: #091c32;
color: #fff;
}
.container {
overflow: hidden;
position: relative;
}
.scroll {
border: 5px solid #000;
padding: 0 10px;
max-width: 250px;
margin: 0 auto;
max-height: 400px;
overflow: auto;
}
.box {
width: 100%;
height: 205px;
border: 2px solid #000;
background: red;
margin: 10px 0;
}
.innerBox {
position: absolute;
width: 150px;
height: 50px;
border: 2px solid #fff;
background: blue;
transform: translate(-50%, -50%);
}
<h1>Lorem Ipsum</h1>
<div class="container">
<div class="scroll">
<div class="box">
<div class="innerBox">Hello</div>
</div>
<div class="box">
<div class="innerBox">World</div>
</div>
<div class="box">
<div class="innerBox">Hello</div>
</div>
<div class="box">
<div class="innerBox">World</div>
</div>
</div>
</div>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam non dapibus risus.</p>
Thank you to everyone who helped :)
Upvotes: 0