Use .scrollIntoView() on a Cypress query that yields the element: cy.get('#footer').scrollIntoView(). To check the result, query the element again and assert that it is visible. Use cy.scrollTo() instead when you want to move a window or scrollable container to a position such as the top, bottom, or specific coordinates.
Scroll a specific element into view
.scrollIntoView() is an element command, so call it on a query result—not as cy.scrollIntoView(selector). For example:
As an Amazon Associate I earn from qualifying purchases.
cy.get('#footer').scrollIntoView()
cy.get('#footer').should('be.visible')
The first command finds the element and scrolls it into view. The second makes a fresh query before checking visibility. Cypress documents that it is unsafe to chain further commands that rely on the subject after .scrollIntoView(), so re-querying is a clear pattern for follow-up assertions.
Do these 3 things before closing this tab:
1Fix the driver behind crashes, sound loss and screen glitches2Repair Windows errors before they cause bigger problems3Scan for outdated or missing drivers - takes under a minuteWait for a target that appears later
If the element is rendered asynchronously, Cypress retries the query until it finds a match or the command times out. You can also wait for a meaningful page condition before scrolling:
#1 Best Overall
cy.get('[data-cy="results-loaded"]').should('be.visible')
cy.get('#footer').scrollIntoView()
cy.get('#footer').should('be.visible')
Use an application-specific readiness condition rather than an arbitrary delay when possible.
Choose between .scrollIntoView() and cy.scrollTo()
| Command | Use it for | Example |
|---|---|---|
.scrollIntoView() |
Bringing a particular queried element into view. | cy.get('#footer').scrollIntoView() |
cy.scrollTo() |
Moving the window or a scrollable element to a named position or coordinates. | cy.scrollTo('bottom') |
.scrollTo() on a container |
Moving that container’s own scroll area. | cy.get('.sidebar').scrollTo('bottom') |
cy.scrollTo() supports named positions such as top, center, and bottom, as well as pixel or percentage coordinates. When you chain it from an element, that element needs to be scrollable; ensureScrollable: false can suppress the scrollability error when it may or may not scroll. These distinctions are documented in Cypress’s scrollTo API reference.
Rank #2
Set alignment and account for fixed headers
.scrollIntoView() accepts options for animation duration, easing, logging, offset, and timeout. The documented defaults are duration: 0, easing: 'swing', log: true, offset: { top: 0, left: 0 }, and the configured defaultCommandTimeout for timeout.
If a fixed header covers the target after scrolling, add an offset. Cypress documents this example:
Rank #3
cy.get('#nav').scrollIntoView({ offset: { top: 150, left: 0 } })
Choose an offset that reflects the layout under test; a fixed value may need adjustment if the header height changes across responsive breakpoints.
Understand Cypress’s automatic scrolling for actions
Cypress automatically scrolls an element into view before actionable commands such as clicking or typing. A query like cy.get() or .find() alone does not scroll. If an action should align the target differently, configure scrollBehavior for that action or for the project. Supported values include 'top', 'bottom', 'start', 'end', 'center', 'nearest', per-axis { block, inline } values, and false to disable action scrolling.
Rank #4
Cypress may continue scrolling to nudge an element clear of a fixed or sticky covering element. If you use { force: true } on an action, Cypress skips scrolling, visibility checks, and other actionability checks. That can conceal a genuine visibility problem, so ordinary user-flow tests should generally use the normal actionability path. See Cypress’s interaction guide for action scrolling and actionability behavior.
Recommended Free Tools
Check the Cypress version installed in the project before relying on version-specific settings: per-axis scrollBehavior values and the start/end action alignments were added in 15.20.0. The current interaction guide says Cypress 16’s default visibility algorithm delegates to the browser’s Element.checkVisibility() API.
Assertions and debugging
- After scrolling, assert the condition the test actually needs, such as
.should('be.visible'), rather than treating the scroll command itself as proof that the page is ready. - Assertions added after
.scrollIntoView()are retried until they pass or time out, but the scroll command itself runs once. - Do not use Cypress command snapshots as a precise indicator of scroll position. Cypress notes that snapshots do not reflect accurate scroll positions. Pause through the command sequence or inspect the test-run video to observe movement.
Troubleshooting common failures
“Cannot read properties” or the command has no element subject
.scrollIntoView() needs a DOM element yielded by a query. Start with a selector query such as cy.get('#footer').scrollIntoView(); do not call it as a top-level Cypress command.
The target is found but still appears covered
A fixed or sticky header may overlap the aligned element. Try a suitable offset with .scrollIntoView(), or adjust the action’s scrollBehavior if the issue occurs during a click or other action. Confirm the target is actually visible in the viewport and not hidden by the page’s own CSS.
cy.scrollTo() reports that an element is not scrollable
When scrolling a container, confirm that the queried element is the one with a scrollable area. If scrollability is conditional and the command should proceed either way, Cypress documents ensureScrollable: false as an option.
A forced click passes while the normal click fails
{ force: true } skips scrolling and actionability checks, including visibility checks. Treat the difference as a signal to investigate why the element is obscured, outside the viewport, or otherwise not actionable rather than as proof that the user can interact with it.
The command log does not show the movement you expected
Snapshots do not preserve accurate scroll positions. Observe the sequence while paused or review the test-run video instead.
Or skip the browser setup
For a website screenshot—not to perform Cypress’s in-test element scrolling—you can call ScreenshotNeo directly. Its API captures a URL as an image or PDF; it is a separate option for producing a screenshot, not a replacement for testing element scroll behavior in Cypress. See the ScreenshotNeo API documentation.
Quick Recap
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
ScreenshotNeo accepts and removes cookie or consent banners, newsletter popups, and chat widgets before capture; each cleanup step can be turned off. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and responses include X-Page-Verdict and X-Billed headers. It also provides an MCP server with screenshot, page-info, and PDF-capture tools for AI agents. The free plan includes 1,000 shots per month with no card; paid plans start at $5 for 3,000 shots.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Create a free ScreenshotNeo account.
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.




