HOWTO · JavaScript
How to Scroll to Top in JavaScript
Return a webpage to the top with JavaScript. Compare an immediate jump, smooth scrolling, an anchor link, and an optional jQuery animation.
On this page
Use window.scrollTo(0, 0) to move the current page to its top. To connect it to a button, add a click listener; pass { top: 0, behavior: "smooth" } when you want the browser to animate the movement instead.
Use window.scrollTo() to return to the top
This example creates its own button, then connects it to window.scrollTo(). Put the script in a page after the document body is available, or load it with defer so the button can be added to the document. The small fallback objects make the example runnable in a Node fixture; in a browser, it uses the page’s real document and window.
const inBrowser = typeof document !== "undefined" && typeof window !== "undefined";
const pageDocument = inBrowser ? document : {
body: {
append(button) {
button.click = () => button.listeners.click();
}
},
createElement() {
return {
listeners: {},
addEventListener(name, handler) {
this.listeners[name] = handler;
}
};
}
};
const pageWindow = inBrowser ? window : {
scrollTo(x, y) {
console.log(`scrollTo(${x}, ${y})`);
}
};
const button = pageDocument.createElement("button");
button.type = "button";
button.textContent = "Back to top";
pageDocument.body.append(button);
button.addEventListener("click", () => {
pageWindow.scrollTo(0, 0);
});
if (!inBrowser) button.click();
scrollTo(0, 0)
The two arguments are the horizontal and vertical scroll positions. Setting each to 0 returns the page to the upper-left corner. Use this immediate form when the jump should happen at once, such as after a short action where an animation would be distracting.
Add smooth scrolling with window.scrollTo()
Pass an options object to window.scrollTo() to request smooth movement. This standalone version uses the same small Node fallback so its click handler can be demonstrated outside a browser:
const inBrowser = typeof document !== "undefined" && typeof window !== "undefined";
const pageDocument = inBrowser ? document : {
body: {
append(button) {
button.click = () => button.listeners.click();
}
},
createElement() {
return {
listeners: {},
addEventListener(name, handler) {
this.listeners[name] = handler;
}
};
}
};
const pageWindow = inBrowser ? window : {
scrollTo(options) {
console.log(`scrollTo(top: ${options.top}, behavior: ${options.behavior})`);
}
};
const button = pageDocument.createElement("button");
button.type = "button";
button.textContent = "Back to top";
pageDocument.body.append(button);
button.addEventListener("click", () => {
pageWindow.scrollTo({ top: 0, behavior: "smooth" });
});
if (!inBrowser) button.click();
scrollTo(top: 0, behavior: smooth)
The top property sets the vertical destination, and behavior: "smooth" asks the browser to animate the scroll. The native options form does not provide a duration setting. If you need a particular duration, use a library animation or implement a custom animation. A page-level CSS rule such as html { scroll-behavior: smooth; } can also make ordinary scrolling smooth, but it does not create a button or a return-to-top action by itself.
Use an anchor link to jump to the top
An anchor is a useful no-script option. Give the start of the page an ID, for example <header id="page-top">, then link to it with <a href="#page-top">Back to top</a>. Activating the link navigates to that fragment, updates the URL fragment, and moves focus/navigation to the target according to browser behavior. Choose a target that exists once on the page; if a fixed header covers it, account for that with CSS such as scroll-margin-top on the target.
Use jQuery to scroll to the top
If the page already loads jQuery, its animate() method can animate the scrollTop property on the document’s scrolling elements. This example adds a button and binds the animation. In a browser, load jQuery before this script; if it is missing, the example throws a clear error. The small fallback is used only by the Node fixture.
const inBrowser = typeof document !== "undefined" && typeof window !== "undefined";
if (inBrowser && typeof globalThis.jQuery !== "function") {
throw new Error("jQuery is required for this example. Load jQuery before this script.");
}
const $ = inBrowser ? globalThis.jQuery : (selector, attributes) => {
if (selector === "<button>") {
return {
...attributes,
appendTo() { return this; },
on(name, handler) { this.handler = handler; return this; }
};
}
return {
animate(properties, duration) {
console.log(`animate(scrollTop: ${properties.scrollTop}, duration: ${duration})`);
}
};
};
const button = $("<button>", {
type: "button",
text: "Back to top"
}).appendTo("body");
button.on("click", () => {
$("html, body").animate({ scrollTop: 0 }, 800);
});
if (!inBrowser) button.handler();
animate(scrollTop: 0, duration: 800)
Here, scrollTop: 0 is the destination and 800 is the animation duration in milliseconds. jQuery is an optional dependency; use the native method when the page does not already need the library. Respect the visitor’s reduced-motion preference if you add a custom animation or other motion effects.
Choose the right approach
Use window.scrollTo(0, 0) for a direct jump from JavaScript. Choose the options form when smooth movement is helpful and a browser-controlled duration is sufficient. Use an anchor when the action should work as ordinary page navigation without JavaScript. Choose jQuery when it is already part of the project and its duration argument fits the interaction. In a single-page application, call the native method after the route or view changes if the application does not already manage scroll position. For a normal link or button, keep the control’s purpose clear to assistive technology and make sure keyboard users can activate it.