JSFiddle - React, Tailwind, and code Playground
by brigand
HTML
<a href="#3">third</a>
<a href="#5">fifth</a>
<a href="#10">tenth</a>
<div>
<h2>1<span class="target" id="1"></span></h2>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Soluta ducimus voluptatem obcaecati, nobis at, quasi nulla aut architecto repudiandae in laborum accusantium repellendus. Quasi recusandae sequi, facere illo sit doloribus.</p>
</div>
<div>
<h2>2<span class="target" id="2"></span></h2>
<p>Tenetur pariatur, molestias minus sit corrupti. Debitis obcaecati id dolorum fugit, voluptate illum harum corporis consequuntur assumenda optio mollitia dolore numquam eos dignissimos alias eveniet laborum tempora, eligendi earum explicabo.</p>
</div>
<div>
<h2>3<span class="target" id="3"></span></h2>
<p>Dolorem modi adipisci illo, pariatur deserunt praesentium mollitia blanditiis eaque dicta. Qui, eligendi! Accusamus eaque libero, eos consectetur sapiente deserunt in aut dolorum molestiae quisquam rem omnis illo blanditiis nobis.</p>
</div>
<div>
<h2>4<span class="target" id="4"></span></h2>
<p>Ad numquam molestiae, minima quia quod ratione placeat soluta, fuga tempore dolorem nam voluptas sed maxime, adipisci cupiditate magnam doloremque dignissimos totam. Repudiandae incidunt architecto quidem, natus labore expedita, sunt!</p>
</div>
<div>
<h2>5<span class="target" id="5"></span></h2>
<p>Architecto, debitis qui illum necessitatibus, id inventore pariatur, earum dolorem obcaecati eius voluptas vero aliquam quasi rem mollitia neque. Ipsa incidunt, exercitationem, aliquid explicabo repellendus doloribus dignissimos ratione voluptate nulla.</p>
</div>
<div>
<h2>6<span class="target" id="6"></span></h2>
<p>Molestias provident illum aliquid vel, mollitia quas dolore sapiente blanditiis illo excepturi eum facilis magni nisi quos dolorum sit, laboriosam labore esse vitae, distinctio omnis eveniet, deleniti! Sit, sint, error?</p>
</div>
<div>
<h2>7<span class="target" id="7"></span></h2>
<p>Id quam dolorum mollitia, assumenda...
CSS
h2 {
position: relative;
}
.target:target {
width: 100%;
height: 3px;
background: hotpink;
}
JavaScript
const TOP_PADDING = 100;
let lastHash = null;
let time = null;
let hashDirty = false;
window.addEventListener('hashchange', () => {
if (time && time > Date.now() - 100) {
update();
time = Date.now();
hashDirty = false;
} else {
hashDirty = true;
}
})
window.addEventListener('scroll', () => {
if (hashDirty) {
update();
} else {
time = Date.now();
}
});
function update() {
const id = document.location.hash.replace('#', '');
if (!id) {
return;
}
const target = document.getElementById(id);
const y = target.getBoundingClientRect().top + window.scrollTop;
window.scrollTo(0, y - TOP_PADDING);
}