Something I’ve learned that wasn’t included in the Learn curriculum was the
progress
element. Now what that does is show the progress of a task. In the
case of this page. It shows how far down the page a user has scrolled. This can
be beneficial to a long webpage such as a blog post. Another reason one could
use the progress element is to show a loading bar for something.
1<body>2 <progress value="0" max="100"></progress>3 ...the rest of your content4</body>
1progress::-webkit-progress-bar {2 background-color: transparent;3}45progress::-webkit-progress-value {6 background-image: linear-gradient(135deg, #52e5e7 0%, #130cb7 100%);7}89progress::-moz-progress-bar {10 background-image: linear-gradient(135deg, #52e5e7 0%, #130cb7 100%);11}1213progress {14 position: fixed;15 left: 0;16 top: 0;17 z-index: 2;18 width: 100%;19 height: 3px;20 appearance: none;21 background: none;22 border: none;23}
1function youReadThisMuch() {2 const scroll = window.pageYOffset; // window.scrollY isnt supported in IE3 const bodyHeight = document.body.offsetHeight;4 const windowHeight = window.innerHeight;5 const scrollPercent = (scroll / (bodyHeight - windowHeight)) * 100;6 document.querySelector('progress').value = scrollPercent;7}89window.addEventListener('scroll', youReadThisMuch);
1class Progress extends React.Component {2 state = { progress: 0 };3 }45 // add the listener when the component mounts6 componentDidMount() {7 window.addEventListener('scroll', this.handleScroll, { passive: true });8 }910 // remove the listener when the component unmounts11 componentWillUnmount() {12 window.removeEventListener('scroll', this.handleScroll);13 }1415 handleScroll = () => {16 const scroll = window.pageYOffset; // window.scrollY is less supported17 const bodyHeight = document.body.offsetHeight;18 const windowHeight = window.innerHeight;19 const scrollPercent = (scroll / (bodyHeight - windowHeight)) * 100;20 const maxMinscroll = Math.min(100, Math.max(0, scrollPercent));21 this.setState({ progress: maxMinscroll });22 }2324 render() {25 return (26 <progress value={this.state.progress} max="100">27 // for styling im using styled-jsx but you should be able to do the same with another css-in-js method28 <style jsx>{29 progress::-webkit-progress-bar {30 background-color: transparent;31 }3233 progress::-webkit-progress-value {34 background-image: linear-gradient(135deg, #52E5E7 0%, #130CB7 100%);35 }3637 progress::-moz-progress-bar {38 background-image: linear-gradient(135deg, #52E5E7 0%, #130CB7 100%);39 }4041 progress {42 position: fixed;43 top: 0;44 left: 0;45 width: 100%;46 z-index: 2;47 height: 3px;48 appearance: none;49 background: none;50 border: none;51 }52 }</style>53 </progress>54 );55 }56}5758export default Progress;
1// useScrollProgress.js2import { useState, useEffect } from 'react';3const useScrollProgress = () => {4 const [scrollProgress, setScrollProgress] = useState(0); // initialize the value5 const handleScroll = () => {6 const scroll = window.pageYOffset;7 const bodyHeight = document.body.offsetHeight;8 const windowHeight = window.innerHeight;9 const scrollPercent = (scroll / (bodyHeight - windowHeight)) * 100;10 const maxMinscroll = Math.min(100, Math.max(0, scrollPercent));11 setScrollProgress(maxMinscroll);12 };1314 useEffect(() => {15 window.addEventListener('scroll', handleScroll, { passive: true });16 handleScroll(); // call it right away so the scroll position is set on page refresh17 return () => {18 window.removeEventListener('scroll', handleScroll); // make sure to remove the listener on umount19 };20 }, []); // passing an empty array as the second arg to useEffect will make sure this code is only run on mount21 return scrollProgress;22};2324export default useScrollProgress;
1// Layout.js2import React from 'react';3import styled from 'styled-componenets';45const ScrollProgress = styled.progress`6789101112131415161718192021222324`;2526const Layout = ({ children }) => {27 const scrollProgress = useScrollProgress();28 return (29 <div>30 <ScrollProgress value={scrollProgress} max={100} />31 </div>32 );33};