Question
How to Get the X and Y Position of an HTML Element in JavaScript
Question
I want to get the X and Y position of HTML elements such as img and div in JavaScript.
For example, how can I read the position of an element on the page so I can know where it appears horizontally and vertically?
Short Answer
By the end of this page, you will understand how to read an HTML element’s position in JavaScript, when to use getBoundingClientRect(), how scrolling affects coordinates, and how this differs from properties like offsetTop and offsetLeft.
Concept
In JavaScript, an element’s position can mean different things depending on the coordinate system you use.
The most common question is: Where is this element located on the screen or page?
There are two important coordinate systems:
- Viewport coordinates: position relative to the visible browser window
- Document coordinates: position relative to the full page, including the scrolled area
The most reliable modern way to get an element’s visible position is:
const rect = element.getBoundingClientRect();
console.log(rect.left, rect.top);
This gives you:
rect.left→ X positionrect.top→ Y position
These values are relative to the viewport, not the full document.
If you want the position relative to the whole page, add the current scroll offset:
const rect = element.getBoundingClientRect();
const x = rect.left + window.scrollX;
const y = rect.top + window.scrollY;
This concept matters because many UI tasks depend on exact positioning:
- placing tooltips
- aligning popups
- detecting whether an element is visible
- drag-and-drop interactions
- animations triggered by scroll position
A common beginner mistake is assuming there is only one "position". In reality, the correct answer depends on whether you want the element’s location in the viewport, inside a parent, or on the full page.
Mental Model
Think of a web page like a large poster seen through a small window.
- The poster is the full document.
- The window is the browser viewport.
- The element might be at one spot on the poster, but its visible position changes as you scroll the window.
So there are two useful answers to “Where is the element?”
- Inside the window → use
getBoundingClientRect() - On the full poster → use
getBoundingClientRect()plus scroll values
This is why scrolling changes top and left from getBoundingClientRect(), even though the element has not moved in the document.
Syntax and Examples
Basic syntax
const element = document.querySelector("div");
const rect = element.getBoundingClientRect();
console.log(rect.left); // X
console.log(rect.top); // Y
Example: get the position of a div
<div id="box">Hello</div>
<script>
const box = document.getElementById("box");
const rect = box.getBoundingClientRect();
console.log("X:", rect.left);
console.log("Y:", rect.top);
</script>
Explanation
getElementById("box")gets the elementgetBoundingClientRect()returns a rectangle describing its size and positionrect.leftis the horizontal positionrect.topis the vertical position
Get page position instead of viewport position
const rect = box.getBoundingClientRect();
const x = rect.left + window.scrollX;
const y = rect.top + window.scrollY;
console.log(x, y);
Use this when you want the element’s location on the full page.
Example with an image
<img id="photo" src="image.jpg" alt="Example image">
<script>
const photo = document.getElementById("photo");
const rect = photo.getBoundingClientRect();
console.log("Viewport X:", rect.left);
console.log("Viewport Y:", rect.top);
</script>
The same approach works for most HTML elements, including div, img, button, and more.
Step by Step Execution
Consider this code:
<div id="card" style="margin-top: 200px; margin-left: 100px;">Card</div>
<script>
const card = document.getElementById("card");
const rect = card.getBoundingClientRect();
console.log(rect.left);
console.log(rect.top);
</script>
What happens step by step
- JavaScript finds the element with
id="card". - It calls
getBoundingClientRect()on that element. - The browser calculates the element’s size and position in the viewport.
rect.leftstores the distance from the left edge of the viewport.rect.topstores the distance from the top edge of the viewport.- The values are printed to the console.
Important detail
If the page is scrolled:
rect.topchangesrect.leftmay also change if there is horizontal scrolling
Trace example
Imagine the element is located 100 pixels from the left side of the page and 500 pixels from the top of the page.
If the user has scrolled down 200 pixels:
- document Y =
500 - viewport Y =
300
So:
const rect = card.getBoundingClientRect();
console.log(rect.top); // 300
console.log(rect.top + window.scrollY); // 500
This shows the difference between viewport position and document position.
Real World Use Cases
Developers read element positions in many practical situations:
Tooltips and dropdowns
A tooltip often needs to appear next to a button.
const buttonRect = button.getBoundingClientRect();
tooltip.style.left = `${buttonRect.right}px`;
tooltip.style.top = `${buttonRect.top}px`;
Scroll-based animations
You can check when an element enters the viewport.
const rect = section.getBoundingClientRect();
if (rect.top < window.innerHeight) {
console.log("Element is visible or entering view");
}
Drag-and-drop interfaces
When dropping an item, you may compare mouse coordinates with element positions.
Canvas or overlay alignment
If you draw a highlight box over an element, you need its exact screen location.
Testing and automation
UI tests sometimes verify whether an element appears in the expected place.
Real Codebase Usage
In real projects, developers usually use element positions as part of larger patterns rather than by themselves.
Guard clauses
Make sure the element exists before reading its position.
const modal = document.querySelector(".modal");
if (!modal) return;
const rect = modal.getBoundingClientRect();
Recalculate on resize or scroll
Positions can change when:
- the window resizes
- the page scrolls
- content loads later
- fonts or images change layout
function updatePosition() {
const rect = target.getBoundingClientRect();
console.log(rect.left, rect.top);
}
window.addEventListener("scroll", updatePosition);
window.addEventListener("resize", updatePosition);
Positioning floating UI
Popovers, menus, and custom dropdowns often use getBoundingClientRect() to place themselves near another element.
Validation before measurement
Sometimes code waits until the DOM is loaded.
document.addEventListener("DOMContentLoaded", () => {
const box = document.getElementById("box");
if (!box) return;
console.log(box.getBoundingClientRect());
});
Error avoidance in dynamic apps
In apps where elements appear later, developers measure positions after rendering is complete.
Common Mistakes
1. Confusing viewport position with page position
Broken assumption:
const rect = element.getBoundingClientRect();
console.log(rect.top); // Not always page Y
Why it happens:
rect.topis relative to the viewport- scrolling changes it
Fix:
const y = element.getBoundingClientRect().top + window.scrollY;
2. Reading the element before it exists
Broken code:
const box = document.getElementById("box");
console.log(box.getBoundingClientRect());
If the script runs before the element is parsed, box may be null.
Fix:
document.addEventListener("DOMContentLoaded", () => {
const box = document.getElementById("box");
if (!box) return;
console.log(box.getBoundingClientRect());
});
3. Using offsetTop when a viewport measurement is needed
offsetTop is not the same as getBoundingClientRect().top.
offsetTopis relative to an offset parentgetBoundingClientRect().topis relative to the viewport
Choose the one that matches your goal.
4. Forgetting that layout can change
Images, fonts, resizing, or dynamic content can move elements after the first measurement.
Avoid this by recalculating when needed.
5. Assuming CSS transforms do not matter
Methods like getBoundingClientRect() reflect the rendered position and size, including transforms in many cases. If an element is visually moved, the measured rectangle may also change.
Comparisons
| Method | What it gives | Relative to | Best use |
|---|---|---|---|
getBoundingClientRect() | Exact rendered position and size | Viewport | Most UI positioning tasks |
rect.top + window.scrollY | Page Y position | Document | Full-page coordinates |
rect.left + window.scrollX | Page X position | Document | Full-page coordinates |
offsetTop | Vertical offset | Offset parent | Layout calculations inside containers |
offsetLeft | Horizontal offset | Offset parent | Layout calculations inside containers |
clientTop / clientLeft | Border widths | Element itself | Rarely used for page position |
getBoundingClientRect() vs offsetTop
const rect = element.getBoundingClientRect().top;
const offset = element.offsetTop;
- Use
rectwhen you care about where the element appears on screen - Use
offsetTopwhen you care about position within layout relative to a parent context
Which should beginners use?
For most cases involving “What is this element’s X and Y position?”, start with:
element.getBoundingClientRect()
It is the clearest and most practical option.
Cheat Sheet
// Viewport position
const rect = element.getBoundingClientRect();
const x = rect.left;
const y = rect.top;
// Document position
const pageX = rect.left + window.scrollX;
const pageY = rect.top + window.scrollY;
Key properties
rect.left→ X relative to viewportrect.top→ Y relative to viewportrect.right→ right edge relative to viewportrect.bottom→ bottom edge relative to viewportrect.width→ width of elementrect.height→ height of element
Rules to remember
getBoundingClientRect()is usually the best choice for element position- Its values change when the page scrolls
- Add
window.scrollXandwindow.scrollYfor page coordinates - Check that the element exists before measuring it
- Measure after the DOM is loaded if needed
Common pattern
function getPagePosition(element) {
const rect = element.getBoundingClientRect();
return {
x: rect.left + window.scrollX,
y: rect.top + window.scrollY
};
}
FAQ
How do I get the X and Y position of a div in JavaScript?
Use getBoundingClientRect():
const rect = div.getBoundingClientRect();
console.log(rect.left, rect.top);
Does getBoundingClientRect() return page coordinates?
No. It returns coordinates relative to the viewport. Add window.scrollX and window.scrollY for page coordinates.
What is the difference between top and offsetTop?
rect.topis relative to the viewportoffsetTopis relative to the element’s offset parent
They are not interchangeable.
Why does the Y value change when I scroll?
Because getBoundingClientRect() measures position relative to the visible browser window, not the full document.
Can I use this for images too?
Yes. getBoundingClientRect() works for img, div, button, and most other HTML elements.
When should I measure an element’s position?
Usually after the element exists in the DOM, and sometimes after layout has settled if images or dynamic content affect placement.
Mini Project
Description
Build a small position inspector that shows the X and Y coordinates of an element when a button is clicked. This demonstrates how to read both viewport coordinates and full page coordinates in a practical way.
Goal
Create a page where clicking a button displays an element’s viewport and document position.
Requirements
- Add an HTML element to measure, such as a
div. - Add a button that triggers the position lookup.
- Show both viewport coordinates and document coordinates.
- Use
getBoundingClientRect()in the solution.
Keep learning
Related questions
Add a Favicon to a Static HTML Page
Learn how to add a favicon to static HTML pages, use correct paths and icon formats, and troubleshoot browser caching and local-file issues.
Allow Only Numeric Input (0-9) in HTML Input Using jQuery
Learn how to allow only digits 0-9 in an HTML input using jQuery, with examples, validation tips, common mistakes, and best practices.
Apply CSS !important with jQuery .css()
Learn why jQuery .css() cannot set !important and how to use CSSStyleDeclaration.setProperty() to apply inline important styles safely.