Tạo nút back to top và back to bottom codepen năm 2024

Having a "back to top" button on a website is important. It allows users to easily scroll back to the top of the page.

Most websites rely on JavaScript to toggle the visibility of the button based on the amount of scroll. In this post, I will show you how to create such an effect using only CSS.

We will explore two kinds of effects – a "sliding" and a "fading" effect.

Here is an overview of what we are building in this part:

Click to see the full code


  
Back to Top & # 8593;
body {
  display: grid;
  grid-template-columns: auto 0px; 
}
.top {
  --offset: 50px; 
  position: sticky;
  bottom: 20px;      
  margin-right: 10px; 
  place-self: end;
  margin-top: calc(100vh + var(--offset));
  /* visual styling */
  text-decoration: none;
  padding: 10px;
  font-family: sans-serif;
  color: 
# fff;
  background: 
# 000;
  border-radius: 100px;
  white-space: nowrap;
}
p {
  font-size: 25px;
}

Sliding "back to top" button using CSS

If you scroll, the "back to top" button will appear and will stick at the bottom of the page. Click on it and you will get back to the top!

You will find no JavaScript in there. We'll only use CSS to make the button appear when you scroll the page.

It's cool, right? Let's dissect the code to understand the magic behind it.

The HTML Structure


  
...

Inside the

body {
  display: grid;
  grid-template-columns: auto 0px; 
}
.top {
  --offset: 50px; 
  position: sticky;
  bottom: 20px;      
  margin-right: 10px; 
  place-self: end;
  margin-top: calc(100vh + var(--offset));
  /* visual styling */
  text-decoration: none;
  padding: 10px;
  font-family: sans-serif;
  color: 
# fff;
  background: 
# 000;
  border-radius: 100px;
  white-space: nowrap;
}
p {
  font-size: 25px;
}

6 tag, we create a

body {
  display: grid;
  grid-template-columns: auto 0px; 
}
.top {
  --offset: 50px; 
  position: sticky;
  bottom: 20px;      
  margin-right: 10px; 
  place-self: end;
  margin-top: calc(100vh + var(--offset));
  /* visual styling */
  text-decoration: none;
  padding: 10px;
  font-family: sans-serif;
  color: 
# fff;
  background: 
# 000;
  border-radius: 100px;
  white-space: nowrap;
}
p {
  font-size: 25px;
}

7 where we put the content of the website. Right after that, we add our "back to top" button as a link.

For the sake of the article, I will keep the button as simple as possible but you can use whatever you want (an image, an icon, and so on). All you need is to keep the usage of

body {
  display: grid;
  grid-template-columns: auto 0px; 
}
.top {
  --offset: 50px; 
  position: sticky;
  bottom: 20px;      
  margin-right: 10px; 
  place-self: end;
  margin-top: calc(100vh + var(--offset));
  /* visual styling */
  text-decoration: none;
  padding: 10px;
  font-family: sans-serif;
  color: 
# fff;
  background: 
# 000;
  border-radius: 100px;
  white-space: nowrap;
}
p {
  font-size: 25px;
}

8 combined with

body {
  display: grid;
  grid-template-columns: auto 0px; 
}
.top {
  --offset: 50px; 
  position: sticky;
  bottom: 20px;      
  margin-right: 10px; 
  place-self: end;
  margin-top: calc(100vh + var(--offset));
  /* visual styling */
  text-decoration: none;
  padding: 10px;
  font-family: sans-serif;
  color: 
# fff;
  background: 
# 000;
  border-radius: 100px;
  white-space: nowrap;
}
p {
  font-size: 25px;
}

9.

That's it! We are done with the HTML structure.

The CSS Code

We first start by styling our button. For this part, it's up to you to be creative and build your own button. I will use a basic button (


  
...

  1. styled like this:

.top {
  text-decoration: none;
  padding: 10px;
  font-family: sans-serif;
  color: 
# fff;
  background: 
# 000;
  border-radius: 100px;
}

Which will get us the following result:

Tạo nút back to top và back to bottom codepen năm 2024

Let's move to the main CSS. The effect we are aiming for uses two CSS techniques:

  1. CSS Grid to create the main structure
  2.  your content goes here  >  
    
    ...

    1 to be able to keep the button at the bottom of the screen

Our structure will be a grid of two columns – one for the content and another one for the "back to top" button. For this, we add the following code:

body {
  display: grid;
  grid-template-columns: auto auto;
}

This gives us the following result:

Yes, it looks "ugly" but don't worry. This is due to the default stretch alignment of CSS Grid. We have to disable it and place our button at the bottom using


  
...

2.

Now let's introduce


  
...

1 by adding this code:

.top {
  position: sticky;
  bottom: 20px; 
}

Our button is fixed at the bottom right of our screen thanks to our "sticky" behavior. Now we need to control that behavior to make the button initially hidden. For this, we will use


  
...

4 with a value equal to the screen height (


  
...

5 ).

See that? Our button appears only when we scroll the screen and then remains fixed. We are getting closer!

Let's do better by adding an offset. Our


  
...

4 will become:

.top {
  --offset: 100px; 
  margin-top: calc(100vh + var(--offset));
}

The above means: "After 100px of scrolling, show the button". To the screen height, we add an offset (that we define using a CSS variable) to control when the button should appear.

The final touch is to make the column width of the button equal to 0 by changing


  
...

7 into


  
...

8.

Oops, the button is messed up! Since we reduced the space of the button to 0, the latter will try to fit that space by adding line breaks. To fix this, we simply add


  
...

9 to disable the line breaks.

We made our first CSS-only "back to top" button with a sliding effect.

  • You can adjust the offset to control when the button should appear
  • Using

    .top { text-decoration: none; padding: 10px; font-family: sans-serif; color:

    fff;

    background:

    000;

    border-radius: 100px; }

    0 and

    .top { text-decoration: none; padding: 10px; font-family: sans-serif; color:

    fff;

    background:

    000;

    border-radius: 100px; }

    1 you can control the distance from the bottom right corner of the screen.

Let's not forget that you can easily style the button as you want. Here is another idea using the same code structure:

Click to see the full code


  
Back to Top & # 8593;
body {
  display: grid;
  grid-template-columns: auto 0px; 
}
.top {
  --offset: 50px; 
  position: sticky;
  bottom: 20px;      
  margin-right: 10px; 
  place-self: end;
  margin-top: calc(100vh + var(--offset));
  /* visual styling */
  width: 45px;
  aspect-ratio: 1;
  background: 
# ff8b24;
  border-radius: 10px;
}
.top:before {
  content: "";
  position: absolute;
  inset: 30%;
  transform: translateY(20%) rotate(-45deg);
  border-top: 5px solid 
# fff;
  border-right: 5px solid 
# fff;
}
p {
  font-size: 25px;
}

How to Make a Fading Back to Top Button

Let's tackle the second type of button where we will have a "fading" effect. Here's an overview of what we will create here:

Click to see the full code


  
body {
  display: grid;
  grid-template-columns: auto 0px; 
}
.top {
  --offset: 50px; 
  position: sticky;
  bottom: 20px;      
  margin-right: 10px; 
  place-self: end;
  margin-top: calc(100vh + var(--offset));
  /* visual styling */
  text-decoration: none;
  padding: 10px;
  font-family: sans-serif;
  color: 
# fff;
  background: 
# 000;
  border-radius: 100px;
  white-space: nowrap;
}
p {
  font-size: 25px;
}

0 Fading "back to top" button using CSS

Like the previous effect, you will find zero JavaScript code. That fading effect is handled with only CSS.

Let's dig into this one!

The HTML structure

body {
  display: grid;
  grid-template-columns: auto 0px; 
}
.top {
  --offset: 50px; 
  position: sticky;
  bottom: 20px;      
  margin-right: 10px; 
  place-self: end;
  margin-top: calc(100vh + var(--offset));
  /* visual styling */
  text-decoration: none;
  padding: 10px;
  font-family: sans-serif;
  color: 
# fff;
  background: 
# 000;
  border-radius: 100px;
  white-space: nowrap;
}
p {
  font-size: 25px;
}

1

It's very similar to the previous example. We've simply added an extra wrapper around our "back to top" button.

The CSS code

I will skip the part where we style the button since it's the same as the previous effect.

This effect also relies on CSS grid and


  
...

1. We'll also use a third technique which is the

.top {
  text-decoration: none;
  padding: 10px;
  font-family: sans-serif;
  color: 
# fff;
  background: 
# 000;
  border-radius: 100px;
}

3 property (the one that will simulate the fading effect).

Let's start with the main setting:

body {
  display: grid;
  grid-template-columns: auto 0px; 
}
.top {
  --offset: 50px; 
  position: sticky;
  bottom: 20px;      
  margin-right: 10px; 
  place-self: end;
  margin-top: calc(100vh + var(--offset));
  /* visual styling */
  text-decoration: none;
  padding: 10px;
  font-family: sans-serif;
  color: 
# fff;
  background: 
# 000;
  border-radius: 100px;
  white-space: nowrap;
}
p {
  font-size: 25px;
}

2

We define our two-column layout where the

.top {
  text-decoration: none;
  padding: 10px;
  font-family: sans-serif;
  color: 
# fff;
  background: 
# 000;
  border-radius: 100px;
}

4 is the second one. We make the latter a flex container and we place the button at the very bottom using

.top {
  text-decoration: none;
  padding: 10px;
  font-family: sans-serif;
  color: 
# fff;
  background: 
# 000;
  border-radius: 100px;
}

5. Finally, we use


  
...

1 to have the button fixed at the bottom right of the screen.

Now let's introduce the

.top {
  text-decoration: none;
  padding: 10px;
  font-family: sans-serif;
  color: 
# fff;
  background: 
# 000;
  border-radius: 100px;
}

3 property to create the fading effect. To understand this trick, I will first use a background to illustrate how it works.

In the above, I applied the following gradient to

.top {
  text-decoration: none;
  padding: 10px;
  font-family: sans-serif;
  color: 
# fff;
  background: 
# 000;
  border-radius: 100px;
}

4:

body {
  display: grid;
  grid-template-columns: auto 0px; 
}
.top {
  --offset: 50px; 
  position: sticky;
  bottom: 20px;      
  margin-right: 10px; 
  place-self: end;
  margin-top: calc(100vh + var(--offset));
  /* visual styling */
  text-decoration: none;
  padding: 10px;
  font-family: sans-serif;
  color: 
# fff;
  background: 
# 000;
  border-radius: 100px;
  white-space: nowrap;
}
p {
  font-size: 25px;
}

3

If you scroll, you will notice that the button will move from the green area to the red one. The green area is equal to the screen height.

Imagine that the green area is the "invisible" part of the

.top {
  text-decoration: none;
  padding: 10px;
  font-family: sans-serif;
  color: 
# fff;
  background: 
# 000;
  border-radius: 100px;
}

4 and the red one is the "visible" part. This is what

.top {
  text-decoration: none;
  padding: 10px;
  font-family: sans-serif;
  color: 
# fff;
  background: 
# 000;
  border-radius: 100px;
}

3 will be doing if we consider the same gradient.

In this last demo, we changed

body {
  display: grid;
  grid-template-columns: auto auto;
}

1 with

.top {
  text-decoration: none;
  padding: 10px;
  font-family: sans-serif;
  color: 
# fff;
  background: 
# 000;
  border-radius: 100px;
}

3 and we used a transparent/opaque combination of colors instead of the green/red one. The button now appears only on scroll!

To get the fading effect, we need to increase the distance between both colors. Let's introduce a CSS variable and update the mask like below:

body {
  display: grid;
  grid-template-columns: auto 0px; 
}
.top {
  --offset: 50px; 
  position: sticky;
  bottom: 20px;      
  margin-right: 10px; 
  place-self: end;
  margin-top: calc(100vh + var(--offset));
  /* visual styling */
  text-decoration: none;
  padding: 10px;
  font-family: sans-serif;
  color: 
# fff;
  background: 
# 000;
  border-radius: 100px;
  white-space: nowrap;
}
p {
  font-size: 25px;
}

4

The transparent color ends at


  
...

5, and the opaque one start at

body {
  display: grid;
  grid-template-columns: auto auto;
}

4. We have a fading of

body {
  display: grid;
  grid-template-columns: auto auto;
}

5 between transparent and opaque which gives us the following result:

We are almost there! Our button is fading like expected. We are simply missing the offset variable to control when the fading effect should happen.

For this, we do the same as the previous effect by introducing the

body {
  display: grid;
  grid-template-columns: auto auto;
}

6 variable:

The final touch is to make the column width of

.top {
  text-decoration: none;
  padding: 10px;
  font-family: sans-serif;
  color: 
# fff;
  background: 
# 000;
  border-radius: 100px;
}

4 equal to 0 using


  
...

8

body {
  display: grid;
  grid-template-columns: auto 0px; 
}
.top {
  --offset: 50px; 
  position: sticky;
  bottom: 20px;      
  margin-right: 10px; 
  place-self: end;
  margin-top: calc(100vh + var(--offset));
  /* visual styling */
  text-decoration: none;
  padding: 10px;
  font-family: sans-serif;
  color: 
# fff;
  background: 
# 000;
  border-radius: 100px;
  white-space: nowrap;
}
p {
  font-size: 25px;
}

5

Our second "back to top" button is done! Like the previous one, you can easily control the offset, the fading effect, and the position by adjusting the CSS variables, the

.top {
  text-decoration: none;
  padding: 10px;
  font-family: sans-serif;
  color: 
# fff;
  background: 
# 000;
  border-radius: 100px;
}

0 property, and the

.top {
  text-decoration: none;
  padding: 10px;
  font-family: sans-serif;
  color: 
# fff;
  background: 
# 000;
  border-radius: 100px;
}

1 property.

Thank you for reading!

For more CSS tips, follow me on Twitter.



Learn to code for free. freeCodeCamp's open source curriculum has helped more than 40,000 people get jobs as developers. Get started