The 'back to top' button
Here is my tutorial on making a 'back to top' button without JavaScript. Please also refer to these very helpful design guidelines. Do let me know in the comments if there is anything here I can be doing differently, especially if I've missed anything regarding accessibility.
Why?
I recently built a portfolio site for a freelance journalist who required a lightweight portfolio site (which I did with Eleventy), where she could host her articles and have visitors contact her.
When I got to designing the full-length article page itself, I wanted to provide a button for readers to get back to the top since there is information that could be of interest after reading: a link to download the original article as a PDF, another to the online article, details like when it was written and so on.
How to implement it?
I asked Google how this could be done - I find it helpful to get different perspectives on solutions before diving into code. I was surprised to find that every answer involved using JavaScript / jQuery. Unless I'm missing something, most code concerning layout that can be done with CSS, should be. JavaScript breaks more easily, requires more work by the browser and not all users run JavaScript.
If you already know about CSS' position
property, skip to the code.
Getting into position
We need to understand the various CSS positions:
-
static
: this is the default value for every element and is named only so that it can be referred to when describing what other positions do. A more helpful name might benone
. The only time you would ever need to use it would be to remove an element'sposition
that had been set elsewhere in a less specific declaration block, i.e. you never need to use it (just go and remove theposition
property from that other block). Think ofstatic
as 'unpositioned', in that it just happens to be where it ends up on the page. This is very useful, because you want most of your elements to 'end up' where you'd expect... it's just that you don't need to apply this property in order for that to happen. As far as I know, this is the most anyone has ever written about thestatic
position. -
relative
: this establishes the element on the page, relative to where you'd expect it to be (itsstatic
position). If you addleft: 20px;
it will move 20px from the left edge of where you'd expect it to be. If you make an elementrelative
without also changing its position, it might look like nothing has happened but your CSS now knows it is there on purpose (unlike an 'unpositioned'static
element), and so it can now be used as a reference for any child elements. -
absolute
: anabsolute
positioned element will go anywhere on the page relative to its closest parent that isn'tstatic
, orbody
if it doesn't have one. Withtop: 0;
this will line up the top of theabsolute
element with the top of its closest positioned parent. -
fixed
: sets the position of an element relative to the window rather than anything on the page - the Dev.to navbar that you can see at the top isfixed
, for example, so it scrolls with your screen not with the page (unless you've changed this default in your settings). -
sticky
: this toggles betweenrelative
andfixed
. It will behave like arelative
element until it gets to itssticky
position, and staysfixed
there until its containing element no longer accommodates its position and it toggles back again. This CSSposition
has been around since 2013 and is up to 95% global usage when using the -webkit- prefix according to caniuse.
Putting it all together
So, we're going to make a relative
page (<main>
) with an absolute
scrollbar (<div>
) that contains a sticky
button (er, the 'button' is in fact an anchor element, since it navigates rather than triggering an event.. so let's call it a link from now on: <a>
).
We won't want to navigate 'back to top' whilst we're already there, so the scrollbar should begin below where the screen loads, i.e. at least 100% of the viewport height from the top of main
. Once we do see the link, we want it to stay in the bottom right, because that's where users expect to find it. Let's say there's a <footer>
at the end of the page, and we want to prevent the link scrolling to the bottom of <main>
, so the scroll bar will also be offset from the bottom.
Here is the most basic implementation of the 'back to top' link without using any JavaScript:
The HTML
<body>
<main>
<section>Words</section> <!--your page content-->
<div class="scroll-top"> <!--scrollbar at the end of main-->
<a class="scroll-top__link" href="#">Back to top</a> <!--href="#" navigates to the top of the page-->
</div>
</main>
<footer>Footer</footer>
</body>
The CSS
main {position: relative;} /* to place scrollbar /
section {height: 300vh;} / so we can scroll /
footer {height: 5rem;} / a typical footer height */
.scroll-top {
position: absolute; /* relative to its positioned <main> parent /
top: 120vh; / starts below the bottom of the screen /
bottom: 3rem; / stops scrolling before the end /
right: 2rem; / offset from right hand side */
}
.scroll-top__link {
position: -webkit-sticky; /* for Safari /
position: sticky; / 'relative' until element reaches... /
top: 90vh; / 90% viewport height from the top, when it becomes 'fixed' - until its container toggles it back to 'relative' */
}
The JavaScript
¯\_(ツ)_/¯
The final product
I included an outline on all the elements so you can see how position
is coming into play.
Let's add lots of text to our <section>
so we don't have to give it an arbitrary height, and introduce smooth scrolling, colour, hover opacity and some padding in our CSS. Here's what that looks like in practice:
So there it is, all you need to make a 'back to top' link without any JavaScript.
edit: href="#"
in an anchor tag tells the browser to scroll to the top of the page without adding to the history, so this shouldn't affect user navigation.
much later edit: the div
/ invisible scroll bar obviously sits on top of the page, so anything underneath it is unclickable. This is a problem for links in text underneath the path of the button.
Top comments (15)
JS devs be like " where are my animationsssss"
You mean
html {scroll-behavior: smooth;}
?Haha! What kind of animations are you thinking about?
all those gimmicy animations, like lets a smooth scrolling to top (like a river :D) or an top arrow that changes color depending on how bottom we are on page etc!
Love the idea of colour changing when scrolling! Or perhaps fading in to full opacity as you get to the bottom...
well, it kind of works but messes up with browser history, user will have to click back button twice which is a bad UX, so just, please, stick to the js solution instead of link
Hey Vitaly! Thanks for your comment. What browser are you using?
href="#"
just navigates to the top of page, it doesn't add to the history in the browser which I should have mentioned in the article, I'll update that now. If you have any other reasons to suggest using JS on top of CSS I'd love to hear them.The question is more, what browser doesn't add it to the history? Both the latest Firefox and Chrome add # to the history.
Anyway, it's a good idea if you don't want to use onScroll event. You just can add a little bit JS to replace the link with a button.
Yep, that's what I've meant, when replacing js with css, do not forget about the UX
Noice
I like this! A couple of the websites I help manage has this effect, but I wasn't sure how it was achieved.
Very elegant : )
Very kind thank you!
Amazing! learned alot!