Question

How to Scroll to an Element with jQuery Animation

javascriptjqueryscroll

Question

I have the following input element:

<input type="text" class="textfield" value="" id="subject" name="subject">

There are other elements on the page as well, such as additional input fields and textarea elements.

When the user clicks on the #subject input, I want the page to scroll smoothly to the last element on the page. The last element is a submit button:

<input type="submit" class="submit" id="submit" name="submit" value="Ok, Done.">

I would like the scroll to move downward to that button with a smooth animation that is not too fast. I am using the latest version of jQuery and would prefer to do this using built-in jQuery features rather than a plugin.

Short Answer

By the end of this page, you will understand how to use jQuery to scroll the page to a specific element when another element is clicked. You will learn how click handlers, animate(), and offset().top work together to create a smooth scrolling effect, and how this pattern is used in real interfaces such as forms, navigation links, and validation flows.

Concept

Smooth scrolling in jQuery usually works by changing the scroll position of the page over time instead of jumping instantly.

The core idea is:

  1. Detect a user action such as a click.
  2. Find the vertical position of the target element.
  3. Animate the page's scroll position until it reaches that target.

In jQuery, this is commonly done with:

  • $(selector).click(...) or .on('click', ...) to detect the click
  • $('#target').offset().top to get the target element's position from the top of the document
  • $('html, body').animate({ scrollTop: ... }, duration) to scroll smoothly

Why this matters:

  • It improves user experience by guiding the user visually.
  • It helps long forms feel easier to navigate.
  • It is often used in landing pages, navigation menus, validation summaries, and step-by-step forms.

Without animation, the page can jump abruptly. With animation, users can see where they are being taken.

Mental Model

Think of the web page as a long sheet of paper inside a window.

  • The window shows only part of the page.
  • The scroll position decides which part you are currently viewing.
  • The target element, such as #submit, has a known location on that paper.
  • jQuery's animate() acts like a smooth elevator moving the window down to that location.

So instead of teleporting the page view to the submit button, you smoothly slide there over a short period of time.

Take Quiz

Syntax and Examples

The basic jQuery pattern looks like this:

$('#subject').on('click', function () {
  $('html, body').animate({
    scrollTop: $('#submit').offset().top
  }, 800);
});

What each part does

  • $('#subject') selects the input that the user clicks.
  • .on('click', ...) runs code when that input is clicked.
  • $('#submit').offset().top gets the vertical position of the submit button.
  • $('html, body').animate(...) smoothly changes the page scroll position.
  • 800 is the duration in milliseconds.

Full example

<input type="text" id="subject" name="subject">

<div style="height: 1200px;"></div>

<input type="submit" id="submit" value="Ok, Done.">

<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
<script>
  $('#subject').on('click', function () {
    $('html, body').animate({
      scrollTop: $('#submit').offset().top
    }, 1000);
  });
</script>

Adding a small top offset

Sometimes you do not want the target element touching the very top of the viewport.

$('#subject').on('click', function () {
  $('html, body').animate({
    scrollTop: $('#submit').offset().top - 20
  }, 1000);
});

This scrolls slightly above the submit button.

Step by Step Execution

Consider this example:

<input type="text" id="subject">
<input type="submit" id="submit" value="Send">
$('#subject').on('click', function () {
  var targetTop = $('#submit').offset().top;

  $('html, body').animate({
    scrollTop: targetTop
  }, 1000);
});

Here is what happens step by step:

  1. jQuery finds the element with id subject.
  2. It attaches a click event listener to that element.
  3. The user clicks inside the input field.
  4. The click callback function runs.
  5. $('#submit') finds the submit button.
  6. .offset().top reads how far that button is from the top of the document.
  7. That value is stored in targetTop.
  8. $('html, body').animate(...) starts changing the page's scrollTop value.
  9. Over 1000 milliseconds, the page scrolls from its current position to targetTop.
  10. The submit button comes into view smoothly.

Example trace

If #submit is 1800 pixels from the top of the page:

  • targetTop becomes 1800
  • jQuery animates scrollTop from the current value, for example 200, to 1800
  • The page visually moves downward until the submit button is reached

Real World Use Cases

Smooth scrolling to an element is common in many real applications:

  • Long forms: Clicking a field or button scrolls to the next important section.
  • Validation errors: After form submission, the page scrolls to the first invalid field.
  • Single-page navigation: Menu links scroll to sections like About, Pricing, or Contact.
  • Checkout pages: Clicking a summary item scrolls to payment or shipping details.
  • Help panels: A link scrolls the user to a related explanation lower on the page.
  • Chat or activity feeds: The interface scrolls to the newest message or item.

In your case, the pattern helps guide the user from the subject field down to the final submit action.

Take Quiz

Real Codebase Usage

In real projects, developers usually do more than just call animate() once.

Common patterns include:

Event binding with .on()

$('#subject').on('click', function () {
  $('html, body').animate({ scrollTop: $('#submit').offset().top }, 800);
});

.on() is preferred because it is consistent and flexible.

Guard clauses for missing elements

In larger codebases, elements may not always exist.

$('#subject').on('click', function () {
  var $target = $('#submit');

  if ($target.length === 0) {
    return;
  }

  $('html, body').animate({
    scrollTop: $target.offset().top
  }, 800);
});

This prevents errors if #submit is missing.

Stopping previous animations

If a user clicks repeatedly, animations can queue up.

$('#subject').on('click', function () {
  $('html, body').stop().animate({
    scrollTop: $('#submit').offset().top
  }, 800);
});

This makes the interaction feel smoother.

Using offsets for sticky headers

If your page has a fixed header, you may need extra space.

var headerHeight = 60;

$('#subject').on('click', function () {
  $('html, body').animate({
    scrollTop: $('#submit').offset().top - headerHeight
  }, 800);
});

Reusable helper function

In a real codebase, scrolling is often wrapped in a function:

function scrollToElement(selector, duration) {
  var $target = $(selector);

  if ($target.length === 0) {
    return;
  }

  $('html, body').stop().animate({
    scrollTop: $target.offset().top
  }, duration || 800);
}

$('#subject').on('click', function () {
  scrollToElement('#submit', 1000);
});

This keeps code organized and reusable.

Common Mistakes

Here are common beginner mistakes when implementing jQuery scrolling.

1. Using # inside the id attribute

This is incorrect:

<input id="#subject">

Use this instead:

<input id="subject">

The # is only used in CSS or jQuery selectors, not inside the actual id value.

2. Scrolling only body or only html

This may work in some browsers but fail in others:

$('body').animate({ scrollTop: 500 }, 800);

Safer approach:

$('html, body').animate({ scrollTop: 500 }, 800);

3. Forgetting .offset().top

This is wrong because .offset() returns an object:

var position = $('#submit').offset();
$('html, body').animate({ scrollTop: position }, 800);

Correct version:

var position = $('#submit').offset().top;
$('html, body').animate({ scrollTop: position }, 800);

4. Binding the event before jQuery or the element is ready

If your script runs too early, the element may not exist yet.

$('#subject').on('click', function () {
  // may fail if DOM is not loaded yet
});

Safer version:

$(function () {
  $('#subject').on('click', function () {
    $('html, body').animate({
      scrollTop: $('#submit').offset().top
    }, 800);
  });
});

5. Animation queue buildup

Repeated clicks can stack animations.

$('html, body').animate({ scrollTop: 1000 }, 800);

Better:

$('html, body').stop().animate({ scrollTop: 1000 }, 800);

6. Target element not found

If #submit does not exist, the code may break or do nothing useful.

var top = $('#submit').offset().top;

Better:

var $target = $('#submit');
if ($target.length) {
  $('html, body').animate({ scrollTop: $target.offset().top }, 800);
}

Comparisons

ApproachWhat it doesProsCons
$('html, body').animate({ scrollTop: ... }, 800)Smoothly scrolls with jQueryBuilt into jQuery, simple, customizableRequires jQuery
window.scrollTo(0, y)Jumps instantly to a positionNative JavaScript, simpleNo animation by default in older styles
element.scrollIntoView()Scrolls an element into viewNative and easy to useLess control in older patterns, not jQuery-based
jQuery plugin for scrollingAdds extra effects or optionsCan provide advanced featuresExtra dependency

jQuery scrolling vs native scrolling

$('html, body').animate({ scrollTop: $('#submit').offset().top }, 800);

vs.

document.getElementById('submit').scrollIntoView({ behavior: 'smooth' });

If you are already using jQuery and want to stay within it, animate() is a natural fit. If you are writing modern JavaScript without jQuery, scrollIntoView() is often simpler.

Take Quiz

Cheat Sheet

// Basic pattern
$('#subject').on('click', function () {
  $('html, body').animate({
    scrollTop: $('#submit').offset().top
  }, 800);
});

Key pieces

  • $('#subject') → source element
  • $('#submit') → target element
  • .on('click', handler) → run code on click
  • .offset().top → get vertical document position
  • .animate({ scrollTop: value }, duration) → animate scroll

Safer version

$(function () {
  $('#subject').on('click', function () {
    var $target = $('#submit');

    if (!$target.length) {
      return;
    }

    $('html, body').stop().animate({
      scrollTop: $target.offset().top
    }, 1000);
  });
});

Useful tips

  • Use $('html, body') for cross-browser reliability.
  • Use .stop() to avoid animation queue buildup.
  • Subtract pixels if you have a fixed header.
  • Do not include # inside the actual HTML id value.
  • Use milliseconds for duration, such as 800 or 1000.

Common durations

  • 400 → quick
  • 800 → smooth
  • 1000 → slower and more noticeable

FAQ

How do I scroll to an element with jQuery?

Use animate() on $('html, body') and set scrollTop to the target element's offset().top.

Why use $('html, body') instead of just $('body')?

Different browsers attach page scrolling to different elements. Using both is a common jQuery solution for better compatibility.

How can I make the scroll slower?

Increase the duration value. For example, use 1000 instead of 400.

What does .offset().top return?

It returns the number of pixels between the top of the document and the top of the target element.

Can I scroll when an input gets focus instead of click?

Yes. Replace click with focus:

$('#subject').on('focus', function () {
  $('html, body').animate({ scrollTop: $('#submit').offset().top }, 800);
});

Why is my code not scrolling?

Common reasons include:

  • jQuery not loaded
  • target element does not exist
  • script runs before the DOM is ready
  • wrong selector
  • wrong id usage

Is there a way to do this without jQuery?

Yes. Modern JavaScript supports scrollIntoView({ behavior: 'smooth' }), but if your project already uses jQuery, animate() works well.

Take Quiz

Mini Project

Description

Build a small long-form page where clicking a text field scrolls smoothly to the submit button at the bottom. This demonstrates how to connect a user event to a target element and animate the page scroll with jQuery.

Goal

Create a working form that smoothly scrolls from the subject field to the submit button when the subject field is clicked.

Requirements

  • Add a text input with the id subject.
  • Add enough content between the top and bottom of the page so scrolling is visible.
  • Add a submit button with the id submit at the bottom.
  • Use jQuery to scroll smoothly to the submit button when #subject is clicked.
  • Make the animation last about 1 second and prevent animation queue buildup.
Take Quiz

Keep learning

Related questions

View more