<div>
  <p>스크롤을 해보자!!</p>
  <div class="root">
    <div class="root-margin"></div>
    <div class="wrapper">
    </div>
    <div class="wrapper">
    </div>
    <div class="wrapper">
    </div>
  </div>
  <div class="wrapper">
  </div>
</div>
div {
  text-align: center;
  font-size: 50px;
  font-weight: bold;
}

.root {
  border: 5px solid blue;
  height: 200px;
  overflow: scroll;
  position: relative;
}

.root-margin {
  position: absolute;
  width: 100%;
  height: 100px;
  background-color: orange;
}

.root-margin::after {
  content: '루트 마진';
  line-height: 100px;
}

.wrapper {
  width: 150px;
  height: 150px;
  margin-bottom: 100px;
  margin-left: auto;
  margin-right: auto;
  background-color: red;
  opacity: 0;
  transition: opacity 0.5s;
}

.wrapper.visible {
  opacity: 1;
}
const option = {
  root: document.querySelector('.root'),
  rootMargin: '100px 0px 0px 0px',
  threshold: 1.0
};

const io = new IntersectionObserver((entries, observer) => {
  entries.forEach((entry) => {
    if(entry.isIntersecting){
      entry.target.classList.add('visible');
    } else {
      entry.target.classList.remove('visible');
    }
  });                            
}, option);

document.querySelectorAll('.wrapper').forEach((wrapper) => io.observe(wrapper));
Run Pen

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.