Skip to content

Instantly share code, notes, and snippets.

@nanna-dk
Last active September 17, 2021 11:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nanna-dk/0e27b9d89e6949ed7cc563e4b32285ee to your computer and use it in GitHub Desktop.
Save nanna-dk/0e27b9d89e6949ed7cc563e4b32285ee to your computer and use it in GitHub Desktop.
Accessible scroll progress indicator
<script>
document.addEventListener('DOMContentLoaded', () => {
const reduceMotion = window.matchMedia('(prefers-reduced-motion: reduce)');
if (reduceMotion.matches) {
return;
}
let scrollPosition = 0;
let tick = false;
const scrollProgress = () => {
let progressbar = document.getElementById('horizontal-scroll');
let winScroll = document.body.scrollTop || document.documentElement.scrollTop;
let height = document.documentElement.scrollHeight - document.documentElement.clientHeight;
let scrolled = (winScroll / height) * 100;
scrolled = Math.round(scrolled);
progressbar.setAttribute('aria-valuenow', scrolled);
progressbar.setAttribute('aria-valuetext', 'Scroll progress: ' + scrolled + '%');
progressbar.style.setProperty("--scrollPercentage", scrolled + '%');
}
const appendProgressbar = () => {
let target = document.querySelector('header:first-of-type');
let bar = document.createElement('div');
bar.classList.add('progress');
bar.innerHTML = '<div class="progress-bar" id="horizontal-scroll" role="progressbar" aria-valuetext="Scroll progress: 0%" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" tabindex="-1"></div>';
let fragment = document.createDocumentFragment();
fragment.appendChild(bar);
target.appendChild(fragment);
}
appendProgressbar();
window.addEventListener('scroll', () => {
scrollPosition = window.scrollY;
if (!tick) {
window.requestAnimationFrame(function() {
scrollProgress();
let top = window.pageYOffset || document.documentElement.scrollTop;
let el = document.querySelector('.progress');
el.classList.toggle('in-view', top > 20);
tick = false;
});
tick = true;
}
passive: true;
});
});
</script>
<style>
:root {
--scrollPercentage: 0;
}
.progress {
width: 100%;
height: 1px;
background: #e9ecef;
opacity: 0;
}
.progress-bar {
height: 100%;
background-color: #901a1e;
width: var(--scrollPercentage);
}
.in-view {
position: fixed;
top: 0;
z-index: 11;
opacity: 1;
height: 10px;
}
</style>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment