# Implement smooth scrolling in pure Javascript

Smooth scrolling is something very cool, we all like. Most of the time, people add it to their websites via jQuery plugins. Although those plugins are great, they might not be a good fit if your are a guy called Jimmy who doesn’t want to add jQuery to his project. If you are this guy, stay with me, I will show you how to implement smooth scrolling yourself, with vanilla Javascript.

Smooth scrolling, carousels, games,  and many other dynamic things we see on webpages, are all based on a powerful javascript feature: animations. An animation consists in moving an element from one state to another, by incrementally changing one or many of its properties during a period of time.

Thinking of smooth scrolling, the animation here will consist in scrolling a webpage from its current scroll position to a target position, by incrementally changing it’s scroll position, during a period of time.
Okay, we now know that smooth scrolling is a kind of animation, what’s next ?

## Picking an easing function

As I said in the preceding section, to make our page scroll smoothly, we will need to incrementally change it’s scroll position. But the most important thing, is the rate at which that position will change. Does the value speed up initially and then slow down ? Does the value instead start slowly and then speed up? An easing function, is what we use to calculate this rate.

Easing functions are based on mathematical equations, and we will cover them in another article.

Now, we need to choose an easing function for implementing our smooth scrolling. Let’s pick the easeInOutQuad function from Robert Penner’s very popular easing functions. You can find them all on Github. The easeInOutQuad function will make our page scrolling fast at the beginning, and then slow as it comes to the target.

```//easeInOutQuad
function easing(t, b, c, d) {
t /= d / 2;
if (t < 1) return c / 2 * t * t + b;
t--;
return -c / 2 * (t * (t - 2) -1) + b;
}```

## Writing the smooth scrolling function

### Computing the page current scroll position

`var startPosition = window.scrollY || window.pageYOffset;`

Both of the `window.scrollY` and `window.pageYOffset` properties contain the number of pixels that the webpage is currently scrolled from the top.

### Computing the target element position

`var targetPosition = target.getBoundingClientRect.top();`

Here we assume `target` is the scroll target element. The `getBoundingClientRect`  method called on an element, returns a  `DOMRect` object, which contains the `left`, `top`, `right`, `bottom`, `x`, `y`, `width`, `height` properties describing the border-box in pixels; the `top` property is the one we need here.

### Computing the distance between the page current scroll position and the target element position

`var distance  = targetPosition - startPosition;`

### Putting the blocks together

```/*
* target is the element we want to scroll to
* duration is the scroll delay in ms
*/

function smoothScroll (target, duration) {
var startPosition = window.scrollY || window.pageYOffset;
var targetPosition = target.getBoundingClientRect.top();
var distance = targetPosition - startPosition;
var timeStart = null;

function loop(timeCurrent) {
if(timeStart === null) timeStart = timeCurrent;

timeElapsed = timeCurrent - timeStart;

next = easing(timeElapsed, startPosition, distance, duration);

// Vertically scroll from the current scroll position to next
window.scrollTo(0, next);

// Rerun the animation until the delay(duration) expires.
if(timeElapsed < duration) window.requestAnimationFrame(loop);
}

// Our good old easeInOutQuad function
function easing(t, b, c, d) {
t /= d / 2;
if(t < 1) return c / 2 * t * * t + b;
t--;
return -c / 2 * (t * (t - 2) - 1) + b;
}

// Start running the animation
window.requestAnimationFrame(loop);
}```

The `window.requestAnimationFrame()` method tells the browser that we are going to perform an animation. It takes a callback method (`loop`) that will run on each update. We keep running the animation until the scrolling delay(`duration`) has expired.

Each time it’s called, the `loop` function receives as a default argument, the current `timestamp`.  Thanks to our `easing` method, we are able to calculate the `next` position to scroll to. Then, we use the `window.scrollTo()` method to incrementally scroll.

### Binding the click event on links to the smoothScroll function

```document.querySelector('a').onclick = function(event) {
smoothScroll(event.target, 1000); // scroll delay here will be 1s
}```

That’s it ! We have just implemented our own smooth scrolling function in pure javascript.