October DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsWindows FixRecommendedWindows errors stealing your time? Find the fix fastScan stability, cleanup and performance issues.Fix NowOctober DealsAmazon USDeal season is back - check today's better picksAmazon US: current deals, useful picks and tech finds.See Picks×
Skip to content
browser automation

How to Scroll to an Element in Selenium (Java and Python)

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Find the target element, then use Selenium 4.2 or newer’s wheel action to bring it into view. In Java: new Actions(driver).scrollToElement(target).perform();. In Python: ActionChains(driver).scroll_to_element(target).perform(). These methods scroll an off-screen element so its bottom is aligned with the bottom of the viewport. Use a distance action for a precise amount, an origin-based action for a nested panel, or JavaScript scrollIntoView() when you need custom alignment around a fixed header.

The shortest working solution

Locate the element first and pass the resulting WebElement to an action chain. The call to perform() is what sends the composed wheel input to the browser.

Java

WebElement target = driver.findElement(By.id("target"));
new Actions(driver)
    .scrollToElement(target)
    .perform();

Python

from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.by import By

target = driver.find_element(By.ID, "target")
ActionChains(driver).scroll_to_element(target).perform()

The convenience method is intended to make an element visible, not to guarantee a particular top offset. When movement is required, Selenium places the element’s bottom at the viewport bottom. If the element is already visible, there may be little or no movement.

Pick the scrolling method that matches the job

Goal Java Python Use it when
Bring a WebElement into view scrollToElement(element) scroll_to_element(element) You care about visibility and have a target element.
Scroll an exact distance scrollByAmount(deltaX, deltaY) scroll_by_amount(delta_x, delta_y) You need a repeatable wheel delta rather than element alignment.
Scroll a particular panel or region scrollFromOrigin(origin, deltaX, deltaY) scroll_from_origin(origin, delta_x, delta_y) The page has a nested scroll container or another wheel origin.
Choose top, center, or custom alignment JavaScript scrollIntoView({block, inline}) A fixed header overlaps the target or you need browser-native alignment.

Positive vertical deltas scroll down and negative values scroll up. Wheel actions model user input and expose an origin; scrollIntoView changes the DOM element’s position according to browser alignment options.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Version and browser requirements

Wheel input was added to Selenium’s Actions API in version 4.2. Use a current Selenium 4 release in both your language binding and driver stack. The official Selenium wheel guide labels its examples “Chromium Only,” so verify the browser and driver combination used by your project before relying on wheel actions across browser families. A script can still use JavaScript scrolling where wheel-action support is not suitable.

  • Start the driver and navigate to the page before locating the target.
  • Locate the element in the same page state in which you intend to scroll.
  • Call perform() (Java) or the Python action-chain equivalent to dispatch the input.
  • For a nested region, identify the scrollable container rather than assuming the document viewport is the origin.

Java: scroll to an element reliably

Basic page example

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.interactions.Actions;

public class ScrollExample {
  public static void main(String[] args) {
    WebDriver driver = new ChromeDriver();
    try {
      driver.get("https://example.com/page");
      WebElement target = driver.findElement(By.id("target"));
      new Actions(driver).scrollToElement(target).perform();
      System.out.println(target.isDisplayed());
    } finally {
      driver.quit();
    }
  }
}

Use any locator that uniquely identifies the element: an ID, CSS selector, XPath, or another Selenium locator. Keep the WebElement reference returned by findElement; the wheel method accepts that object, not a locator string.

Scroll by a known amount

new Actions(driver)
    .scrollByAmount(0, 600)
    .perform();

new Actions(driver)
    .scrollByAmount(0, -400)
    .perform();

Use a positive deltaY to move down and a negative value to move up. A distance action does not know which element you ultimately need, so it is best for pagination, incremental reading, or a controlled animation rather than target discovery.

Python: scroll to an element

Basic page example

from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.by import By

with webdriver.Chrome() as driver:
    driver.get("https://example.com/page")
    target = driver.find_element(By.ID, "target")
    ActionChains(driver).scroll_to_element(target).perform()
    assert target.is_displayed()

Scroll by a known amount

ActionChains(driver).scroll_by_amount(0, 600).perform()
ActionChains(driver).scroll_by_amount(0, -400).perform()

Python uses snake_case method names while Java uses camelCase. The behavior is otherwise the same: the action is queued until perform() runs.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Scrolling a nested panel with an origin

A page can have a document viewport plus independently scrollable elements such as a table, chat history, or side panel. In that case, scrolling the document may leave the desired content hidden. Selenium’s origin-based wheel action lets you select the element that owns the wheel event and then apply deltas.

Java origin example

WebElement panel = driver.findElement(By.cssSelector(".results-panel"));
new Actions(driver)
    .scrollFromOrigin(ScrollOrigin.fromElement(panel), 0, 500)
    .perform();

Python origin example

from selenium.webdriver.common.actions.wheel_input import ScrollOrigin

panel = driver.find_element(By.CSS_SELECTOR, ".results-panel")
origin = ScrollOrigin.from_element(panel)
ActionChains(driver).scroll_from_origin(origin, 0, 500).perform()

If the origin element is off-screen, Python’s API first attempts to move it into view. Offsets that place the origin outside the viewport can raise MoveTargetOutOfBoundsException. Reduce the offset, scroll the containing page first, or choose an origin that is visible and within the intended panel.

Use JavaScript when alignment matters

The browser-native scrollIntoView method exposes alignment options that the wheel convenience method does not. block controls vertical placement (start, center, end, or nearest), while inline controls horizontal placement.

Java

WebElement target = driver.findElement(By.id("target"));
((JavascriptExecutor) driver).executeScript(
    "arguments[0].scrollIntoView({block: 'center', inline: 'nearest'});",
    target
);

Python

target = driver.find_element(By.ID, "target")
driver.execute_script(
    "arguments[0].scrollIntoView({block: 'center', inline: 'nearest'});",
    target,
)

Center alignment is useful when a sticky or fixed header would cover an element placed at the top edge. Another page-side solution is CSS scroll-margin-top on the target, with a value that matches the header’s height. This keeps native scrolling from hiding the element behind the header.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Dynamic pages: locate, scroll, then interact

Scrolling does not wait for a page’s application state. On a page that renders content asynchronously, wait for the target to exist or become usable before locating it, then perform the scroll and the click or assertion. If a framework redraws the list during that wait, discard the old reference and call findElement again; a reference to a node removed from the DOM can become stale.

  • Prefer a stable locator for the actual target rather than a coordinate.
  • Scroll only after the target has been inserted into the DOM.
  • After scrolling, check the element’s displayed or enabled state before clicking.
  • For lazy-loaded sections, allow the application’s own loading cycle to finish before asserting text or taking a screenshot.

Troubleshooting common failures

Nothing moves

Confirm that the target is genuinely outside the viewport and that perform() was called. If the element is already visible, scrollToElement may correctly produce no noticeable movement. For a guaranteed visual change, use a deliberate positive or negative delta.

The wrong area scrolls

This usually means the wheel event is being sent to the document while the content lives in a nested panel. Select the panel as a scroll origin and use scrollFromOrigin or scroll_from_origin.

The target is hidden under a header

Switch to JavaScript with block: 'center', or add an appropriate scroll-margin-top rule to the target element. A plain wheel action does not provide a header-specific offset.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

MoveTargetOutOfBoundsException

With an origin-based action, the origin or its offsets can lie outside the viewport. Bring the origin into view first, reduce the offset, and make sure the selected element is the scrollable region you intended.

Element-not-found or stale-element errors

The locator may run before the page creates the element, or the page may replace it after you found it. Wait for the relevant state, then locate the element immediately before scrolling. If the DOM is replaced, obtain a fresh WebElement and retry once the page is stable.

Works in one browser but not another

Check the browser/driver pairing and Selenium version. Selenium’s wheel guide is explicitly marked Chromium Only, so use the JavaScript method or a browser-specific fallback when your supported matrix includes a browser for which wheel behavior is not established.

Verification and test design

A scroll call succeeding does not prove that the intended content is visible. Follow it with a meaningful assertion: the target is displayed, a nearby label is present, or a click succeeds. For a nested panel, assert the panel’s content changed rather than only checking the document’s scroll position. Keep the assertion close to the action so a later page update cannot hide the cause of a failure.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

When screenshots are part of a test or CI report, capture after the scroll and after any lazy content has rendered. This separates a scrolling defect from a timing or rendering defect.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Or skip the browser setup

If your real goal is a clean image of a URL rather than an interactive Selenium session, ScreenshotNeo provides a website screenshot API and MCP server. One GET request returns PNG, JPEG, WebP, or a PDF. The API can accept a URL, load lazy images, wait for a selector, delay, or network idle, click an element, hide selectors, set headers and cookies, choose device and viewport settings, and capture a selected element.

Here is the one-call cURL form (see the ScreenshotNeo API docs for all parameters):

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

Python

import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)

Node.js

const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);

Before capture, ScreenshotNeo accepts cookie and consent banners like a visitor and removes more than 60 known consent platforms, newsletter popups, and chat widgets; each cleanup step can be disabled. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and every response identifies the result with X-Page-Verdict and X-Billed headers. Its MCP server exposes take_screenshot, get_page_info, and capture_pdf for Claude, Cursor, and other MCP clients. The Free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 shots. Create a free ScreenshotNeo account.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

FAQ

Does Selenium scroll to the element’s top edge?

Not with the wheel convenience method. When movement is needed, its documented result places the element’s bottom at the viewport bottom. Use scrollIntoView when top, center, or another alignment is required.

Which method should I use for a scrollable table?

Use an element-based scroll origin for the table or its scroll container, then provide a vertical delta. Scrolling the document viewport alone may not move the table’s rows.

Can I use these actions for horizontal movement?

Yes. Supply a horizontal delta in scrollByAmount or the origin-based method; keep the vertical delta at zero when only horizontal movement is wanted.

Frequently Asked Questions

Does Selenium scroll to the element’s top edge?

Not with the wheel convenience method. When movement is needed, its documented result places the element’s bottom at the viewport bottom. Use scrollIntoView when top, center, or another alignment is required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Which method should I use for a scrollable table?

Use an element-based scroll origin for the table or its scroll container, then provide a vertical delta. Scrolling the document viewport alone may not move the table’s rows.

Can I use these actions for horizontal movement?

Yes. Supply a horizontal delta in scrollByAmount or the origin-based method; keep the vertical delta at zero when only horizontal movement is wanted.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Read next

Recommended PC Tool
Recommended PC Tool
Windows Errors? Fix Them Before They SpreadFree repair scan
Crashes, No Sound, or Screen Glitches?Free driver scan

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.