Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

199
Views
javascript - How to start update scroll percentage when element is on the top of viewport

When entering the website, this is the first UI you'll see. enter image description here

Then, if you scroll down to the very beginning of section B
I expect the section B will become sticky and the currentPercentage state will start increasing from 0% gradually if you scroll.
enter image description here

When the currentPercentage state reach 100%, the sticky effect will no longer apply to sectionB, then you can scroll down to section C or the bottom of the page.

enter image description here

It's kind of like circle-ci homepage

You can try to scroll in this section.
enter image description here

I think there are a few things we need to figure out for the solution

  1. How to make section B become sticky when scroll position arrives section B
  2. How to scroll and increase the percentage when arriving section B

I've tried thinking in both css and javascript way, still cannot find the solution

I've also done lots of research for this problem for a few days but still not figuring it out.
I believe a lots of developers would like to know how to do this kind of effect in their frontend, and it will be beneficial for other developers to have quicker solution to deal with this kind of UX in the future, since from what I've noticed no one has mentioned this kind of UX handling.

I would be appreciated if someone can answer this question with an example, for the reference for other developers.

App.js

import "./styles.css";
import "bootstrap/dist/css/bootstrap.min.css";

import ProgressBar from "react-bootstrap/ProgressBar";

import { useState } from "react";

export default function App() {
  const [currentProgress, setCurrentProgress] = useState(100);
  return (
    <div className="App">
      <div className="sectionA">Section A</div>
      <div className="sectionB">
        Section B
        <ProgressBar
          now={currentProgress}
          label={`${currentProgress}%`}
          style={{ marginBottom: "16px" }}
        />
      </div>
      <div className="sectionC">Section C</div>
    </div>
  );
}

Codesandbox
https://codesandbox.io/s/mutable-fire-sz19b?file=/src/App.js:0-619

Update 1
I updated the code and can be able to make container B sticky, but dont know how to continue for the UX

App.js

import "./styles.css";
import "bootstrap/dist/css/bootstrap.min.css";

import ProgressBar from "react-bootstrap/ProgressBar";

import { useState } from "react";

export default function App() {
  const [currentProgress, setCurrentProgress] = useState(3);
  return (
    <div className="App">
      <div className="sectionA">Section A</div>
      <div style={{ position: "sticky", top: 0 }}>
        <div className="sectionB">
          Section B
          <ProgressBar
            now={currentProgress}
            label={`${currentProgress}%`}
            style={{ marginBottom: "16px" }}
          />
        </div>
        <div className="sectionC">Section C</div>
      </div>
      <div style={{ minHeight: "400vh", maxHeight: "calc(200vh - 466px)" }} />
    </div>
  );
}

Codesandbox
https://codesandbox.io/s/elated-hawking-n3rvw?file=/src/App.js:0-778

Update 2

Added library react-scroll-percentage to scroll to update currentProgress

However, when the whole containerB exposed in the viewport, the currentProgress will start updating, which is not what I want
enter image description here

What I want is when SectionB reach the top of the viewport, the scrolling will make user feel sticky and then currentProgress will start updating from 0%

App.js

import "./styles.css";
import "bootstrap/dist/css/bootstrap.min.css";
import React, { useState, useEffect } from "react";
import { useScrollPercentage } from "react-scroll-percentage";

import ProgressBar from "react-bootstrap/ProgressBar";

export default function App() {
  const [currentProgress, setCurrentProgress] = useState(0);

  const [ref, percentage] = useScrollPercentage({
    threshold: 1.0
  });
  useEffect(() => {
    setCurrentProgress(percentage * 100);
  }, [percentage]);

  return (
    <div className="App">
      <div className="sectionA">Section A</div>
      <div style={{ position: "sticky", top: 0 }}>
        <div className="sectionB" ref={ref}>
          Section B
          <ProgressBar
            now={currentProgress}
            label={`(${currentProgress})%`}
            style={{ marginBottom: "16px" }}
          />
        </div>
        <div className="sectionC">Section C</div>
      </div>
      <div style={{ minHeight: "400vh", maxHeight: "calc(200vh - 466px)" }} />
    </div>
  );
}

Codesandbox
https://codesandbox.io/s/elated-hawking-n3rvw?file=/src/App.js:0-1029

over 4 years ago · Santiago Trujillo
1 answers
Answer question

0

You need to listen to scroll events, check scrollTop of the scrolling element, and decide what the css and currentProgress need to be. This is easiest when the height of each section is known and constant. The outer element also needs a large predetermined height, to leave room for scrolling.

The code might just be

if (scrollTop > heightofSectionA) {
    //set sectionB css to {position: fixed, top: 0, ...}
    currentProgress = (scrollTop-heightofSectionA)/lengthofSectionB*100
} else {
    //set sectionB css to {position: static}
    currentProgress = 0
}

There is a number of ways the html and css could look. With position: sticky you might not need to change css at all. But as long as you know what the css at any stage of the scroll should look like, you should have no problems switching between them.

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!