How to Implement Smooth Scrolling With CSS & JavaScript

In this tutorial, we’ll learn how to implement smooth scrolling in our web pages. We’ll start with a pure CSS solution and then move on to a common jQuery approach. Next, I’ll explain two pure JavaScript solutions. Finally, we’ll discuss how to prevent smooth scrolling in certain scenarios. 

Just to give you an idea of what we’ll discuss during this tutorial, check out one of the demos we’ll be building:

Let’s get started!

1. Begin With the HTML Markup

For demonstration purposes, we’ll define a header wrapped within a container and four sections. Inside it, we’ll specify a navigation menu and an introductory text. 

Each section will have an id whose value will match the href value of a menu link. This association (what we refer to as a fragment identifier) will allow us to jump to specific parts of our page.

Here’s the HTML:

1
<div class="container">
2
  ...
3
  <header class="page-header">
4
    <nav>
5
      <ul>
6
        <li>
7
          <a href="#...">...</a>
8
        </li>
9
        <!-- more links -->
10
      </ul>
11
    </nav>
12
    <div class="header-text">...</div>
13
  </header>
14
</div>
15
<section class="section" id="">...</section>
16
<section class="section" id="">...</section>
17
<section class="section" id="">...</section>
18
<section class="section" id="">...</section>

2. Define the Styles

The CSS part will be pretty straightforward, nothing extraordinary.

First, we’ll use CSS Grid to layout the page header. The menu will cover one-fourth of the available width, while the text the remaining three-fourths (the responsive stuff isn’t really important here):

1
.page-header {
2
  display: grid;
3
  grid-column-gap: 30px;
4
  grid-template-columns: 1fr 3fr;
5
  padding: 40px 0;
6
  border-top: 1px solid;
7
  border-bottom: 1px solid;
8
  margin-bottom: 150px;
9
}
10

11
.header-text {
12
  font-weight: bold;
13
}

Coming up next, we’ll apply some styles to the sections. Most importantly, we’ll ensure that they will be tall enough, so there’s adequate scrolling inside the page for the effect:

1
/*CUSTOM VARIABLES HERE*/
2

3
.section {
4
  padding: 150px 0;
5
}
6

7
.section:nth-of-type(1),
8
.section:nth-of-type(3) {
9
  background: var(--beige);
10
}
11

12
.section-text {
13
  margin: 50px 0;
14
  max-width: 800px;
15
}
16

17
.section-btn {
18
  display: inline-block;
19
  color: var(--beige);
20
  background: var(--black);
21
  min-width: 200px;
22
  height: 50px;
23
  padding: 9px 40px;
24
  text-align: center;
25
}

That’s all we need so far! If we now click on a specific link, we’ll immediately jump to the relevant page section. 

Check out our initial demo:

Basic HTML stuff, right? Let’s now take it a step further and learn how to navigate to the sections smoothly.

3. Smooth Scrolling With CSS

The easiest and quickest approach for applying smooth scrolling inside a page is via the following rule:

1
html { 
2
  scroll-behavior: smooth; 
3
}

Let’s explain.

There’s a relatively new CSS property called scroll-behavior. This property accepts two values: auto (default) and smooth. As soon as we give scroll-behavior: smooth to the html element, the magic will happen, and we’ll be able to navigate to the target section smoothly.

Note: if you set scroll-behavior: smooth to the body element, smooth scrolling won’t work.

As an additional note, keep in mind that at the time of this writing, there isn’t any speed option defined in the specification for manipulating the animation speed.

Here’s the associated demo:

Solution Review

It’s a great and promising CSS feature, and its browser support gradually grows. That said, even Safari, which lacked support in its previous versions, has started supporting it. 

4. Smooth Scrolling With jQuery

We’ll continue with the traditional jQuery approach. That said, to create smooth scrolling with jQuery, we’ll take advantage of its animate() method. 

Each time we click on a navigation link, we’ll do the following things:

  1. Cancel its default behavior to jump to the corresponding section.
  2. Grab its href attribute value. 
  3. Smoothly navigate to the associated section by animating the scrollTop property. Note that the animate() method allows us to adjust the animation speed. In our case, the animation will last 800ms.

Here’s the jQuery code:

1
$(".page-header ul a").on("click", function (e) {
2
  // 1

3
  e.preventDefault();
4
  // 2

5
  const href = $(this).attr("href");
6
  // 3

7
  $("html, body").animate({ scrollTop: $(href).offset().top }, 800);
8
});

And the related demo:

Solution Review

The major downside of this method is that you have to load an extra JavaScript library. On the contrary, it’s a reliable solution that will work well on different screens/devices, and you can customize the scrolling speed. Go with it only if your project already uses or needs jQuery.

5. Smooth Scrolling With Vanilla JavaScript

At this point, we’ll throw away jQuery and concentrate on two pure JavaScript solutions. Happily enough, it’s much simpler than you might expect. 

Using the scroll() Method

First, we’ll use the scroll() method. The logic for this approach is similar to the previous jQuery implementation. 

Inside this method, we’ll determine the scrolling behavior via the behavior configuration property. This property is the JavaScript representation of the scroll-behavior CSS property and can receive the auto (default), smooth and instant (see upcoming section 7) values. Again here, all we have to do is set the value of the behavior property to smooth.

Here’s the required code:

1
const links = document.querySelectorAll(".page-header ul a");
2

3
for (const link of links) {
4
  link.addEventListener("click", clickHandler);
5
}
6

7
function clickHandler(e) {
8
  e.preventDefault();
9
  const href = this.getAttribute("href");
10
  const offsetTop = document.querySelector(href).offsetTop;
11

12
  scroll({
13
    top: offsetTop,
14
    behavior: "smooth"
15
  });
16
}

Instead of the scroll() method, we could equally have used the scrollTo() and scrollBy() methods. The effect should look the same.

Here’s the associated demo:

Using the scrollIntoView() Method

Beyond the aforementioned scroll methods which are attached to the window object (i.e. window.scroll()), there’s also the scrollIntoView() method which applies to DOM elements. This can accept as well the familiar behavior property with the value set to smooth.

Here’s the code needed for this implementation:

1
const links = document.querySelectorAll(".page-header ul a");
2

3
for (const link of links) {
4
  link.addEventListener("click", clickHandler);
5
}
6

7
function clickHandler(e) {
8
  e.preventDefault();
9
  const href = this.getAttribute("href");
10

11
  document.querySelector(href).scrollIntoView({
12
    behavior: "smooth"
13
  });
14
}

The related demo:

Solutions Review

The native JavaScript version of smooth scrolling requires more code compared to the native CSS property. Like the CSS solution, its support is growing everyday. On the contrary, there’s no easy way to control the scrolling speed unless we write our code.

6. Polyfills Please?

As already discussed, native smooth scrolling with CSS or JavaScript is increasing, yet sometimes you might want to extend the support in older browsers.

In such a case, you can use a polyfill like the popular Smooth Scroll with over 3.5k GitHub stars.

To include it in your projects, grab it from a CDN, then insert it as a script tag before your JavaScript code.

In our case, as soon as we load it in one of our JavaScript demos, the scrolling animation will work in browsers like Safari 14 and devices like iPad Mini 4. But, if we add it in our CSS demo, the scrolling animation won’t work on unsupported browsers/devices.

Here’s one of our aforementioned JavaScript demos with the polyfill embedded:

7. Prevent Smooth Scrolling in HTML

Smooth scrolling is a great feature for enhancing the user experience, but sometimes you might want to prevent it for some elements.

Let’s assume that in our demo there’s also a back-to-top button. By default, we’ll enable smooth scrolling via CSS, but then we’ll override that behavior for that button only.

Method #1

To achieve this, upon button click, we’ll first override the page’s scroll behavior by setting scroll-behavior: auto, and then after navigating to the top of the page, we’ll set it back to smooth.

Here’s the required code:

1
//we have set scroll-behavior: smooth in CSS

2

3
const root = document.documentElement;
4
const back = document.querySelector(".back");
5

6
back.addEventListener("click", function (e) {
7
  e.preventDefault();
8
  root.style.scrollBehavior = "auto";
9
  scroll({
10
    top: document.body.offsetTop
11
  });
12
  root.style.scrollBehavior = "";
13
});

And the associated demo:

Method #2

We can also prevent smooth scrolling in HTML by passing behavior: instant to the scroll() method. At the time of writing, this value isn’t documented in the MDN docs, yet it appears as an option in the editor’s spec. According to my tests, it works at least on the latest versions of Chrome, Firefox, and Edge.

Here’s the previous example with this modification:

Conclusion

That’s it, folks! Today we covered some options for achieving smooth scrolling with CSS and JavaScript (including jQuery). We also examined how to prevent smooth scrolling set in CSS through JavaScript.

I hope you found this exercise useful and have enhanced your front-end knowledge a little bit. If you have ever built something similar in the past, please share it with us via social media.

Challenge: before closing, I have a small challenge for you! Your job is to extend one of our JavaScript demos by including a “back to top” button. The final functionality should work like this demo. Do you accept the challenge? If so, I’d be glad to see your solution!

As always, thanks a lot for reading!


This content originally appeared on Envato Tuts+ Tutorials and was authored by George Martsoukos

In this tutorial, we’ll learn how to implement smooth scrolling in our web pages. We’ll start with a pure CSS solution and then move on to a common jQuery approach. Next, I’ll explain two pure JavaScript solutions. Finally, we’ll discuss how to prevent smooth scrolling in certain scenarios. 

Just to give you an idea of what we’ll discuss during this tutorial, check out one of the demos we’ll be building:

Let’s get started!

1. Begin With the HTML Markup

For demonstration purposes, we’ll define a header wrapped within a container and four sections. Inside it, we’ll specify a navigation menu and an introductory text. 

Each section will have an id whose value will match the href value of a menu link. This association (what we refer to as a fragment identifier) will allow us to jump to specific parts of our page.

Here’s the HTML:

1
<div class="container">
2
  ...
3
  <header class="page-header">
4
    <nav>
5
      <ul>
6
        <li>
7
          <a href="#...">...</a>
8
        </li>
9
        <!-- more links -->
10
      </ul>
11
    </nav>
12
    <div class="header-text">...</div>
13
  </header>
14
</div>
15
<section class="section" id="">...</section>
16
<section class="section" id="">...</section>
17
<section class="section" id="">...</section>
18
<section class="section" id="">...</section>

2. Define the Styles

The CSS part will be pretty straightforward, nothing extraordinary.

First, we’ll use CSS Grid to layout the page header. The menu will cover one-fourth of the available width, while the text the remaining three-fourths (the responsive stuff isn’t really important here):

1
.page-header {
2
  display: grid;
3
  grid-column-gap: 30px;
4
  grid-template-columns: 1fr 3fr;
5
  padding: 40px 0;
6
  border-top: 1px solid;
7
  border-bottom: 1px solid;
8
  margin-bottom: 150px;
9
}
10
11
.header-text {
12
  font-weight: bold;
13
}

Coming up next, we’ll apply some styles to the sections. Most importantly, we’ll ensure that they will be tall enough, so there’s adequate scrolling inside the page for the effect:

1
/*CUSTOM VARIABLES HERE*/
2
3
.section {
4
  padding: 150px 0;
5
}
6
7
.section:nth-of-type(1),
8
.section:nth-of-type(3) {
9
  background: var(--beige);
10
}
11
12
.section-text {
13
  margin: 50px 0;
14
  max-width: 800px;
15
}
16
17
.section-btn {
18
  display: inline-block;
19
  color: var(--beige);
20
  background: var(--black);
21
  min-width: 200px;
22
  height: 50px;
23
  padding: 9px 40px;
24
  text-align: center;
25
}

That’s all we need so far! If we now click on a specific link, we’ll immediately jump to the relevant page section. 

Check out our initial demo:

Basic HTML stuff, right? Let’s now take it a step further and learn how to navigate to the sections smoothly.

3. Smooth Scrolling With CSS

The easiest and quickest approach for applying smooth scrolling inside a page is via the following rule:

1
html { 
2
  scroll-behavior: smooth; 
3
}

Let's explain.

There's a relatively new CSS property called scroll-behavior. This property accepts two values: auto (default) and smooth. As soon as we give scroll-behavior: smooth to the html element, the magic will happen, and we’ll be able to navigate to the target section smoothly.

Note: if you set scroll-behavior: smooth to the body element, smooth scrolling won't work.

As an additional note, keep in mind that at the time of this writing, there isn’t any speed option defined in the specification for manipulating the animation speed.

Here's the associated demo:

Solution Review

It's a great and promising CSS feature, and its browser support gradually grows. That said, even Safari, which lacked support in its previous versions, has started supporting it. 

4. Smooth Scrolling With jQuery

We'll continue with the traditional jQuery approach. That said, to create smooth scrolling with jQuery, we’ll take advantage of its animate() method. 

Each time we click on a navigation link, we’ll do the following things:

  1. Cancel its default behavior to jump to the corresponding section.
  2. Grab its href attribute value. 
  3. Smoothly navigate to the associated section by animating the scrollTop property. Note that the animate() method allows us to adjust the animation speed. In our case, the animation will last 800ms.

Here’s the jQuery code:

1
$(".page-header ul a").on("click", function (e) {
2
  // 1

3
  e.preventDefault();
4
  // 2

5
  const href = $(this).attr("href");
6
  // 3

7
  $("html, body").animate({ scrollTop: $(href).offset().top }, 800);
8
});

And the related demo:

Solution Review

The major downside of this method is that you have to load an extra JavaScript library. On the contrary, it's a reliable solution that will work well on different screens/devices, and you can customize the scrolling speed. Go with it only if your project already uses or needs jQuery.

5. Smooth Scrolling With Vanilla JavaScript

At this point, we’ll throw away jQuery and concentrate on two pure JavaScript solutions. Happily enough, it’s much simpler than you might expect. 

Using the scroll() Method

First, we’ll use the scroll() method. The logic for this approach is similar to the previous jQuery implementation. 

Inside this method, we’ll determine the scrolling behavior via the behavior configuration property. This property is the JavaScript representation of the scroll-behavior CSS property and can receive the auto (default), smooth and instant (see upcoming section 7) values. Again here, all we have to do is set the value of the behavior property to smooth.

Here’s the required code:

1
const links = document.querySelectorAll(".page-header ul a");
2
3
for (const link of links) {
4
  link.addEventListener("click", clickHandler);
5
}
6
7
function clickHandler(e) {
8
  e.preventDefault();
9
  const href = this.getAttribute("href");
10
  const offsetTop = document.querySelector(href).offsetTop;
11
12
  scroll({
13
    top: offsetTop,
14
    behavior: "smooth"
15
  });
16
}

Instead of the scroll() method, we could equally have used the scrollTo() and scrollBy() methods. The effect should look the same.

Here’s the associated demo:

Using the scrollIntoView() Method

Beyond the aforementioned scroll methods which are attached to the window object (i.e. window.scroll()), there’s also the scrollIntoView() method which applies to DOM elements. This can accept as well the familiar behavior property with the value set to smooth.

Here’s the code needed for this implementation:

1
const links = document.querySelectorAll(".page-header ul a");
2
3
for (const link of links) {
4
  link.addEventListener("click", clickHandler);
5
}
6
7
function clickHandler(e) {
8
  e.preventDefault();
9
  const href = this.getAttribute("href");
10
11
  document.querySelector(href).scrollIntoView({
12
    behavior: "smooth"
13
  });
14
}

The related demo:

Solutions Review

The native JavaScript version of smooth scrolling requires more code compared to the native CSS property. Like the CSS solution, its support is growing everyday. On the contrary, there's no easy way to control the scrolling speed unless we write our code.

6. Polyfills Please?

As already discussed, native smooth scrolling with CSS or JavaScript is increasing, yet sometimes you might want to extend the support in older browsers.

In such a case, you can use a polyfill like the popular Smooth Scroll with over 3.5k GitHub stars.

To include it in your projects, grab it from a CDN, then insert it as a script tag before your JavaScript code.

In our case, as soon as we load it in one of our JavaScript demos, the scrolling animation will work in browsers like Safari 14 and devices like iPad Mini 4. But, if we add it in our CSS demo, the scrolling animation won't work on unsupported browsers/devices.

Here’s one of our aforementioned JavaScript demos with the polyfill embedded:

7. Prevent Smooth Scrolling in HTML

Smooth scrolling is a great feature for enhancing the user experience, but sometimes you might want to prevent it for some elements.

Let’s assume that in our demo there’s also a back-to-top button. By default, we'll enable smooth scrolling via CSS, but then we’ll override that behavior for that button only.

Method #1

To achieve this, upon button click, we’ll first override the page’s scroll behavior by setting scroll-behavior: auto, and then after navigating to the top of the page, we’ll set it back to smooth.

Here’s the required code:

1
//we have set scroll-behavior: smooth in CSS

2
3
const root = document.documentElement;
4
const back = document.querySelector(".back");
5
6
back.addEventListener("click", function (e) {
7
  e.preventDefault();
8
  root.style.scrollBehavior = "auto";
9
  scroll({
10
    top: document.body.offsetTop
11
  });
12
  root.style.scrollBehavior = "";
13
});

And the associated demo:

Method #2

We can also prevent smooth scrolling in HTML by passing behavior: instant to the scroll() method. At the time of writing, this value isn’t documented in the MDN docs, yet it appears as an option in the editor’s spec. According to my tests, it works at least on the latest versions of Chrome, Firefox, and Edge.

Here’s the previous example with this modification:

Conclusion

That’s it, folks! Today we covered some options for achieving smooth scrolling with CSS and JavaScript (including jQuery). We also examined how to prevent smooth scrolling set in CSS through JavaScript.

I hope you found this exercise useful and have enhanced your front-end knowledge a little bit. If you have ever built something similar in the past, please share it with us via social media.

Challenge: before closing, I have a small challenge for you! Your job is to extend one of our JavaScript demos by including a “back to top” button. The final functionality should work like this demo. Do you accept the challenge? If so, I’d be glad to see your solution!

As always, thanks a lot for reading!


This content originally appeared on Envato Tuts+ Tutorials and was authored by George Martsoukos


Print Share Comment Cite Upload Translate Updates
APA

George Martsoukos | Sciencx (2021-06-15T07:57:31+00:00) How to Implement Smooth Scrolling With CSS & JavaScript. Retrieved from https://www.scien.cx/2021/06/15/how-to-implement-smooth-scrolling-with-css-javascript/

MLA
" » How to Implement Smooth Scrolling With CSS & JavaScript." George Martsoukos | Sciencx - Tuesday June 15, 2021, https://www.scien.cx/2021/06/15/how-to-implement-smooth-scrolling-with-css-javascript/
HARVARD
George Martsoukos | Sciencx Tuesday June 15, 2021 » How to Implement Smooth Scrolling With CSS & JavaScript., viewed ,<https://www.scien.cx/2021/06/15/how-to-implement-smooth-scrolling-with-css-javascript/>
VANCOUVER
George Martsoukos | Sciencx - » How to Implement Smooth Scrolling With CSS & JavaScript. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2021/06/15/how-to-implement-smooth-scrolling-with-css-javascript/
CHICAGO
" » How to Implement Smooth Scrolling With CSS & JavaScript." George Martsoukos | Sciencx - Accessed . https://www.scien.cx/2021/06/15/how-to-implement-smooth-scrolling-with-css-javascript/
IEEE
" » How to Implement Smooth Scrolling With CSS & JavaScript." George Martsoukos | Sciencx [Online]. Available: https://www.scien.cx/2021/06/15/how-to-implement-smooth-scrolling-with-css-javascript/. [Accessed: ]
rf:citation
» How to Implement Smooth Scrolling With CSS & JavaScript | George Martsoukos | Sciencx | https://www.scien.cx/2021/06/15/how-to-implement-smooth-scrolling-with-css-javascript/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.