It's kinda rare to find a smooth scrolling button that takes you to the top of the page on modern blogging websites, especially the ones that are a long 15 minute read!
However, whenever I come across one, I always tend to use it and appreciate the elegance of this simple button that has such a specific job.
After perusing Stack Overflow and GitHub for solution, I came across an elegant React component that uses Hooks and wanted to share it with this community!
Our button should function like this:
These are following test-cases for our component:
- Button should always be at the right bottom of the page
- Button should be hidden and should only appear when we scroll for a certain height
- On clicking it, we should be smoothly taken to the top of the page
The Hook component achieves the following functionality.
import React, { useEffect, useState } from "react";
export default function ScrollToTop() {
const [isVisible, setIsVisible] = useState(false);
// Top: 0 takes us all the way back to the top of the page
// Behavior: smooth keeps it smooth!
const scrollToTop = () => {
window.scrollTo({
top: 0,
behavior: "smooth"
});
};
useEffect(() => {
// Button is displayed after scrolling for 500 pixels
const toggleVisibility = () => {
if (window.pageYOffset > 500) {
setIsVisible(true);
} else {
setIsVisible(false);
}
};
window.addEventListener("scroll", toggleVisibility);
return () => window.removeEventListener("scroll", toggleVisibility);
}, []);
//scroll-to-top classes: fixed, bottom:0, right:0
return (
<div className="scroll-to-top">
{isVisible && (
<div onClick={scrollToTop}>
<h3>Go up!</h3>
</div>
)}
</div>
);
}
We're almost done! Just import this component in your react file and stick it at the very end.
And voila, it should work!
Here is a basic, quick, and ugly demo of how it should function!
Top comments (25)
I had to build a similar thing a while ago, but without any framework; ended up with much less code by simply adding a scroll event handler that toggles a
top
class on thebody
element. The CSS then just has a rule like.top .scroll-to-top { opacity: 1 }
Damn! That's awesome. Do you have a demo by any chance?
cc-entrance.comcard.de Ignore the fact that it's in German 😁
Also there's a few additional effects other than just fading in and out, which obviously makes the CSS a bit more complex.
This looks so good! I just looked at the event code and the underlying function is almost the same. It's just less code due to being written in pure HTML and CSS I reckon. Correct me if I am wrong!
Yea, I don't think the way I do it is all that different from yours, the only detail that really changes is that I use more of the CSS cascade in an attempt to make it more "generic" :D
This is pretty cool and a great way to get people up and running fast there's one minor change I'd make though.
By moving the function into the
useEffect
it is only declared once rather than on every draw. Also by adding a return to that sameuseEffect
we can stop listening if the component is ever unmounted.As an interesting side point you could look into using
IntersectionObserver
, with a scroll event fallback, if you wanted to improve on performance, but I don't think this would really need it 😉Thank you for pointing out the cleanup for useEffect. I always tend to forget that. I had not considered
IntersectionObserver
since I didn't know there was a performance hit, but I will certainly look into it!You don't need JS for this, as you achieve this with only CSS.
☝️ If you now link to
#top
, your browser will smoothscroll to the top of the page (you don't even need an anchor/element with that name)DONE. 😱
(Not supported in Safari though — Meh 😕)
not working on safari browser. can u fix it?
Since I use Chrome and Firefox, I didn't know it doesn't work on Safari.
This post on Stack Overflow has some suggestions you might find helpful.
stackoverflow.com/questions/560112...
helpful ! thank bro
And of course you want to remove event listener as well? :)
Just updated the code. Thank you for the comment!
Just like back navigation, this functionality is in fact so important that every computer already has a physical button for it: the "Home" key, or shift+space / cmd+up if you don't have one.
Duplicating system or browser behaviour is simply introducing UI inconsistency - not a fan of these.
Damn, two decades of using computers and I didn't know a 'Home' key already does that for you! 🤯
Thank you for the feedback. I tried to get a basic Code Sandbox up and running but Chrome kept on crashing on me.
And the example I used is from my portfolio that I am currently working on. I will post a link as soon as it's live!
Simple yet very useful tutorial. Thanks for sharing 🙌
Glad you found it useful!
Nice, but I think hooks should start with use, like useScrollToTop.
You're right. I think this can be called a Scroll component then! 😅
Nice job bro you helped a lot but can u tell me why this line ?