jakey_dev
jakey_dev

Reputation: 233

How to bring forward div element inside overflow auto?

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

Answers (1)

jakey_dev
jakey_dev

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

Related Questions