Question
How can I retrieve the X and Y coordinates of HTML elements, such as <img> and <div>, using JavaScript? I need to understand which coordinates are relative to the viewport and how to obtain coordinates relative to the full document.
Short Answer
You will learn how to measure an element’s position with JavaScript, choose between viewport-relative and document-relative coordinates, and avoid common issues caused by scrolling, timing, and CSS layout changes.
Concept
An element can have different X and Y positions depending on the coordinate system you mean.
The most useful browser API is element.getBoundingClientRect(). It returns a DOMRect object describing the element’s visible box relative to the viewport: the currently visible browser area.
const box = document.querySelector(".card").getBoundingClientRect();
console.log(box.left); // X coordinate in the viewport
console.log(box.top); // Y coordinate in the viewport
If the page scrolls, viewport coordinates change because the element moves closer to or farther from the visible area. To calculate a position relative to the complete document, add the page’s scroll position.
const x = box.left + window.scrollX;
const y = box.top + window.scrollY;
This matters for tasks such as positioning menus, tooltips, drag-and-drop targets, scroll-based animations, click effects, and measuring layout.
Mental Model
Think of a webpage as a long poster and the browser viewport as a small window placed over that poster.
- Viewport coordinates tell you where an element appears inside the window right now.
- Document coordinates tell you where the element is printed on the full poster.
When you scroll, the window moves over the poster. The element stays in the same document location, but its location inside the window changes.
Syntax and Examples
Use getBoundingClientRect() on a DOM element.
const image = document.querySelector("#profile-image");
const rect = image.getBoundingClientRect();
console.log("Viewport X:", rect.left);
console.log("Viewport Y:", rect.top);
console.log("Width:", rect.width);
console.log("Height:", rect.height);
For document-relative coordinates:
const panel = document.querySelector(".panel");
const rect = panel.getBoundingClientRect();
const x = rect.left + window.scrollX;
const y = rect.top + window.;
.(, x);
.(, y);
Step by Step Execution
Consider this page structure:
<div style="height: 500px;"></div>
<div id="notice">Important notice</div>
const notice = document.querySelector("#notice");
const rect = notice.getBoundingClientRect();
const viewportX = rect.left;
const viewportY = rect.top;
const documentX = rect.left + window.scrollX;
const documentY = rect.top + window.scrollY;
console.log({ viewportX, viewportY, documentX, documentY });
Step by step:
querySelector("#notice")finds thedivelement.getBoundingClientRect()measures its current rendered rectangle.
Real World Use Cases
- Tooltips and popovers: Place a help panel beside the button that opened it.
- Context menus: Position a custom menu near a target element.
- Drag and drop: Compare an item’s rectangle with a drop zone’s rectangle.
- Click indicators: Draw a highlight or ripple at a measured location.
- Scroll effects: Determine whether a section is currently above, inside, or below the viewport.
- Canvas overlays: Convert an element’s page location into coordinates used for an overlay.
- Automated UI testing: Verify that an element is visible or appears in an expected area.
Real Codebase Usage
In production code, developers usually measure elements only when necessary: after rendering, after a resize, after a relevant scroll event, or immediately before positioning another UI component.
A common popover-positioning pattern is:
function positionPopover(anchor, popover) {
const rect = anchor.getBoundingClientRect();
popover.style.position = "fixed";
popover.style.left = `${rect.left}px`;
popover.style.top = `${rect.bottom + 8}px`;
}
position: fixed works naturally with viewport coordinates because both are relative to the viewport.
For an absolutely positioned overlay inside the document, use document coordinates instead:
function positionDocumentOverlay(anchor, overlay) {
const rect = anchor.getBoundingClientRect();
overlay.style.position = "absolute";
overlay.style.left = `${rect.left + .scrollX}px`;
overlay.. = ;
}
Common Mistakes
Treating viewport coordinates as document coordinates
This code is valid, but its values change when the user scrolls:
const rect = element.getBoundingClientRect();
console.log(rect.top);
If you need a stable position on the full page, add window.scrollY and window.scrollX.
const documentY = rect.top + window.scrollY;
Reading style.left and style.top
console.log(element.style.left); // Often an empty string
element.style.left only reads an inline style="left: ..." value. It does not reliably report where an element was rendered by normal layout, flexbox, grid, margins, or stylesheets. Use getBoundingClientRect() for rendered coordinates.
Comparisons
| Approach | Coordinates are relative to | Best use | Important limitation |
|---|---|---|---|
getBoundingClientRect() | Viewport | Visibility checks and fixed-position UI | Changes as the page scrolls |
rect.left + scrollX, rect.top + scrollY | Document | Absolute overlays and page-relative measurements | Must account for scroll values |
offsetLeft, offsetTop | offsetParent | Simple positioning within a layout parent | Not a reliable full-document position |
element.style.left, element.style.top |
Cheat Sheet
const element = document.querySelector("#target");
const rect = element.getBoundingClientRect();
// Relative to the visible browser viewport
const viewportX = rect.left;
const viewportY = rect.top;
// Relative to the full document
const documentX = rect.left + window.scrollX;
const documentY = rect.top + window.scrollY;
leftandtopare the element’s upper-left corner.rightandbottomdescribe the opposite edges.- Viewport coordinates change after scrolling.
- Document coordinates normally stay stable while scrolling.
- Remeasure after layout changes or resize events.
- Match coordinate systems: use viewport coordinates with
position: fixed; use document coordinates with many document-level absolute overlays. - Check that
querySelectorfound an element before measuring it.
FAQ
How do I get the X and Y position of a div in JavaScript?
Select the div and call getBoundingClientRect(). Use rect.left for X and rect.top for Y relative to the viewport.
Does getBoundingClientRect() work for images?
Yes. It works for rendered elements including img, div, buttons, inputs, and SVG elements.
Why does rect.top change when I scroll?
It is measured relative to the viewport. Scrolling moves the visible viewport over the document, so the element’s viewport location changes.
How do I get an element’s position relative to the document?
Add the current scroll offsets: rect.left + window.scrollX and rect.top + window.scrollY.
What is the difference between offsetTop and getBoundingClientRect().top?
offsetTop is relative to an offsetParent. getBoundingClientRect().top is relative to the viewport and represents the rendered box’s current position.
Mini Project
Description
Build a small element inspector that displays the current viewport and document coordinates of a target card. It demonstrates how scrolling changes viewport values while document values remain tied to the page layout.
Goal
Display an element’s X and Y position and update the displayed values when the page scrolls or the window is resized.
Requirements
Use getBoundingClientRect() to measure a target element.
Show both viewport-relative and document-relative X and Y values.
Update the values when the user scrolls.
Update the values when the browser window is resized.
Keep learning
Related questions
Abort Ajax Requests with jQuery jqXHR.abort()
Learn how to cancel an in-progress jQuery Ajax request with jqXHR.abort(), handle abort status safely, and avoid stale UI updates.
Access the Correct this Inside a JavaScript Callback
Learn why JavaScript this changes in callbacks and how to preserve an object context using bind, arrow functions, and event handler patterns.
Add Key-Value Pairs to JavaScript Objects
Learn how to add key-value pairs to JavaScript objects with dot and bracket notation, dynamic keys, examples, and common mistakes.