Approach 1: Anchor Links
The simplest way to send a user back to the top of a page is by utilizing an anchor link. You define a target element at the very top of the page and link to it from a button or link at the bottom.
<body style="height:2000px;">
<div id="pageTop"></div>
<a href="#pageTop" style="position:fixed;right:0;bottom:0">Back to Top</a>
</body>
Approach 2: Manipulating scrollTop
The scrollTop property gets or sets the number of pixels an element's content is scrolled vertically. By setting this value to 0 on the document's body or root element, we force the view back to the top.
<body style="height:2000px;">
<button id="btnTop" style="position:fixed;right:0;bottom:0">Back to Top</button>
<script>
btnTop.onclick = function(){
document.body.scrollTop = document.documentElement.scrollTop = 0;
}
</script>
</body>
Approach 3: Using scrollTo()
The scrollTo(x, y) method scrolls the window to a specific coordinate. Passing (0,0) moves the viewport to the top-left corner of the document.
<body style="height:2000px;">
<button id="btnTop" style="position:fixed;right:0;bottom:0">Back to Top</button>
<script>
btnTop.onclick = function(){
scrollTo(0,0);
}
</script>
</body>
Approach 4: Using scrollBy()
Unlike scrollTo, scrollBy(x, y) scrolls by a relative amount. To go up, we calculate the current scroll position and scroll by the negative equivalent of that value.
<body style="height:2000px;">
<button id="btnTop" style="position:fixed;right:0;bottom:0">Back to Top</button>
<script>
btnTop.onclick = function(){
var currentPos = document.body.scrollTop || document.documentElement.scrollTop;
scrollBy(0, -currentPos);
}
</script>
</body>
Approach 5: Using scrollIntoView()
This method scrolls the parent container such that the selected element is visible to the user. We place a hidden marker at the top and tell the browser to scroll to it when the button is clicked.
<body style="height:2000px;">
<div id="topMarker"></div>
<button id="btnTop" style="position:fixed;right:0;bottom:0">Back to Top</button>
<script>
btnTop.onclick = function(){
topMarker.scrollIntoView();
}
</script>
</body>
UI Enhancement
Instead of a standard button, we can create a floating widget using CSS. This design hides the text "Back to Top" initial and reveals it only on hover, using a triangular arrow as the default visual indicator.
<style>
.scroll-widget{
position:fixed;
right:10px;
bottom: 10px;
height:30px;
width: 50px;
text-align:center;
padding-top:20px;
background-color: lightblue;
border-radius: 20%;
overflow: hidden;
}
.scroll-widget:hover:before{
top:50%
}
.scroll-widget:hover .arrow{
visibility: hidden;
}
.scroll-widget:before{
position: absolute;
top: -50%;
left: 50%;
transform: translate(-50%,-50%);
content:'Back to Top';
width: 40px;
color:peru;
font-weight:bold;
}
.arrow{
visibility: visible;
display:inline-block;
height:20px;
width: 20px;
border: 3px solid black;
border-color: white transparent transparent white;
transform:rotate(45deg);
}
</style>
<body style="height:2000px;">
<div id="scrollWidget" class="scroll-widget">
<div class="arrow"></div>
</div>
</body>
Animation Enhancement
To improve user experience, we can add a smooth scrolling animation using requestAnimationFrame for better performance. The following logic applies to the scrollTop approach, decrementing the scroll position gradually untill it reaches zero.
<script>
var animFrame;
scrollWidget.onclick = function(){
cancelAnimationFrame(animFrame);
animFrame = requestAnimationFrame(function smoothScroll(){
var currentScroll = document.body.scrollTop || document.documentElement.scrollTop;
if(currentScroll > 0){
document.body.scrollTop = document.documentElement.scrollTop = currentScroll - 50;
animFrame = requestAnimationFrame(smoothScroll);
} else {
cancelAnimationFrame(animFrame);
}
});
}
</script>
Final Implementation
Combining the UI widget with the animated scroll logic provides a polished solution. The code below brings together the visual design and the requestAnimationFrame logic for a smooth scroll-to-top experience.
<style>
.scroll-widget{
position:fixed;
right:10px;
bottom: 10px;
height:30px;
width: 50px;
text-align:center;
padding-top:20px;
background-color: lightblue;
border-radius: 20%;
overflow: hidden;
}
.scroll-widget:hover:before{
top:50%
}
.scroll-widget:hover .arrow{
visibility: hidden;
}
.scroll-widget:before{
position: absolute;
top: -50%;
left: 50%;
transform: translate(-50%,-50%);
content:'Back to Top';
width: 40px;
color:peru;
font-weight:bold;
}
.arrow{
visibility: visible;
display:inline-block;
height:20px;
width: 20px;
border: 3px solid black;
border-color: white transparent transparent white;
transform:rotate(45deg);
}
</style>
<body style="height:2000px;">
<div id="scrollWidget" class="scroll-widget">
<div class="arrow"></div>
</div>
</body>
<script>
var animFrame;
scrollWidget.onclick = function(){
cancelAnimationFrame(animFrame);
animFrame = requestAnimationFrame(function smoothScroll(){
var currentScroll = document.body.scrollTop || document.documentElement.scrollTop;
if(currentScroll > 0){
document.body.scrollTop = document.documentElement.scrollTop = currentScroll - 50;
animFrame = requestAnimationFrame(smoothScroll);
} else {
cancelAnimationFrame(animFrame);
}
});
}
</script>