skip to Main Content

I have a block on the page where there is a background line, on the line itself there is a circle that scrolls along with the main scroll

The question is, how can you make it so that, along with the circle, another line of the same color as the circle scrolls along the line, and it all would look something like this:

enter image description here

I tried adding styles to before, but it didn’t work out what I expected

left: 50%;
transform: translate(-50%, -50%);
width: 3px;
height: 40vh;
background: #4f8eff;
box-shadow: inset 0 20vh 10vh -10vh #f6e75e, inset 0 -20vh 10vh -10vh #f6e75e;
z-index: 2;

Everything should be like in the picture that I threw off, the circle should be white inside, and the blue color should completely overlap the yellow when we scrolled to the very top, and the same from the bottom. And in the center of the block, let’s say the blue color should be both above the circle and below, while maintaining the gradient

const circle = document.querySelector(".circle");
const cases = document.querySelectorAll(".case");

circle.style.transition = ""

const handleScroll = () => {
  const {
    height: blockHeight
  } = document.querySelector(".block2").getBoundingClientRect()

  const maxTop = cases[cases.length - 1].offsetTop + cases[cases.length - 1].offsetHeight - 200
  const minTop = cases[0].offsetTop

  let {
    height: startTop
  } = cases[0].getBoundingClientRect()

  const scrollDist = Math.min(maxTop, Math.max(startTop / 2 + window.scrollY, minTop))

  circle.style.top = `${scrollDist}px`
  circle.style.backgroundSize = `17px ${blockHeight}px`
  circle.style.backgroundPosition = `0 ${-scrollDist}px`
}

const handleWindowSizeAndScroll = () => {
  window.removeEventListener("scroll", handleScroll)
  window.removeEventListener("resize", handleScroll)
  window.addEventListener("scroll", handleScroll)
  window.addEventListener("resize", handleScroll)
}

handleScroll()
handleWindowSizeAndScroll()
window.addEventListener("resize", handleWindowSizeAndScroll)
.block1 {
  height: 200px;
  background-color: gray;
}

.block3 {
  height: 600px;
  background-color: gray;
}

.block2 {
  height: 100%;
  position: relative;
}

.block2,
.block2 .circle {
  background: linear-gradient(214deg, rgba(79, 142, 255, 0) 0%, #f5e550 10%, #f5e550 90%, rgba(79, 142, 255, 0) 100%) center/3px calc(100% - 100px) no-repeat;
}

.block2 .circle {
  background: #4f8eff;
  width: 17px;
  height: 17px;
  left: 50%;
  transform: translate(-50%, -50%);
}

.block2 .circle,
.block2 .circle::before {
  position: absolute;
  border-radius: 50%;
}

.block2 .circle::before {
  content: "";
  inset: 3px;
  background-color: white;
}

.block2 .circle::before {
  left: 50%;
  transform: translate(-50%, -50%);
  width: 3px;
  height: 40vh;
  background: #4f8eff;
  box-shadow: inset 0 20vh 10vh -10vh #f6e75e, inset 0 -20vh 10vh -10vh #f6e75e;
  z-index: 2;
}

.text {
  text-align: center;
  padding: 200px 50px;
}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.3.0/css/bootstrap.min.css" integrity="sha512-t4GWSVZO1eC8BM339Xd7Uphw5s17a86tIZIj8qRxhnKub6WoyhnrxeCIMeAqBPgdZGlCcG2PrZjMc+Wr78+5Xg==" crossorigin="anonymous" referrerpolicy="no-referrer"
/>
<div class="block1"></div>
<div class="block2">
  <div class="circle"></div>
  <div class="case">
    <div class="row">
      <div class="col-5 text">Text 1</div>
      <div class="col-2"></div>
      <div class="col-5 text">Text 1</div>
    </div>
  </div>
  <div class="case">
    <div class="row">
      <div class="col-5 text">Text 2</div>
      <div class="col-2"></div>
      <div class="col-5 text">Text 2</div>
    </div>
  </div>
  <div class="case">
    <div class="row">
      <div class="col-5 text">Text 3</div>
      <div class="col-2"></div>
      <div class="col-5 text">Text 3</div>
    </div>
  </div>
</div>
<div class="block3"></div>

2

Answers


  1. Here’s your custom scrollbar. Note that you need to add additional event listeners if you want to be able to grab the thumb and scroll. Try scrolling with mouse-wheel to see the effect.

    const scrollBarEl = document.getElementsByClassName('scroll')[0];
    const scrollEl = document.getElementsByClassName('outer-container')[0];
    scrollEl.addEventListener('scroll', e => {
      const scrollSpan = scrollEl.scrollHeight - scrollEl.clientHeight;
      if (scrollSpan !== 0)
        scrollBarEl.style.setProperty('--scroll', `${scrollEl.scrollTop / scrollSpan * 100}%`)
    })
    .outer-container {
      max-height: 90vh;
      overflow: auto;
    }
    
    .container {
      min-height: 400vh;
    }
    
    .scroll {
      --scroll: 0%;
      position: fixed;
      right: 10px;
      top: 10px;
      bottom: 10px;
      width: 5px;
      background: linear-gradient(to bottom, #ff00, #ff0, #00f var(--scroll), #ff0, #ff00);
    }
    
    .thumb {
      height: 10px;
      width: 10px;
      border: 2px solid #00f;
      border-radius: 50%;
      background: #fff;
      position: absolute;
      top: calc(var(--scroll) - 6px);
      left: -4px;
    }
    <div class='outer-container'>
      <div class='container'>
        <div class='scroll'>
          <div class='thumb'></div>
        </div>
      </div>
    </div>
    Login or Signup to reply.
  2. <!DOCTYPE html>
    <html>
      
    <head>
        <!-- CSS -->
        <style>
            .outer_circle {
                position: relative;
                margin: 50px;
                width: 100px;
                height: 100px;
                border-radius: 50%;
                background: #ffffff;
            }
              
            .inner_circle {
                background-image: linear-gradient(
                         to bottom, rgb(9, 112, 26) 0%,
                         rgb(21, 255, 0) 100%);
                content: '';
                position: absolute;
                top: -20px;
                bottom: -20px;
                right: -20px;
                left: -20px;
                z-index: -1;
                border-radius: inherit;
            }
        </style>
    </head>
      
    <body>
        <div class="outer_circle">
            <div class="inner_circle"></div>
        </div>
    </body>
      
    </html>
    <style>
        .outer_circle {
            position: relative;
            margin: 50px;
            width: 100px;
            height: 100px;
            border-radius: 50%;
            background: #ffffff;
        }
          
        .inner_circle {
            background-image: linear-gradient(
                     to bottom, rgb(9, 112, 26) 0%,
                     rgb(21, 255, 0) 100%);
            content: '';
            position: absolute;
            top: -20px;
            bottom: -20px;
            right: -20px;
            left: -20px;
            z-index: -1;
            border-radius: inherit;
        }
    </style>
    
    
    <div class='outer_circle'>
        <div class='inner_circle'></div>
    </div>
    
     
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search