# Get the X Y Position of an HTML Element in JavaScript

> Use getBoundingClientRect to get an HTML element's window coordinates, add scrollY and scrollX for page coordinates, and account for CSS transforms

**URL:** https://sentry.io/answers/how-do-i-get-the-position-x-y-of-an-html-element/

---

## The Problem

How do you find the (x, y) coordinate of an HTML element on your page? You might want to position a popup next to an element, create a fancy animation, or overlay elements seamlessly.

## The Solution

There are two coordinate systems in HTML:

- The coordinates of the entire page (parts of which may be completely off the screen).
- The coordinates of the elements shown in the window (the user's current viewport).

Let's call these page coordinates and window coordinates. Both of these axes have their origin points (0,0) at the top left of the page or window, with values increasing towards the bottom right.

### Get the Window Coordinate

To get the position of an HTML element in JavaScript relative to the window, use `getBoundingClientRect()`:

```html
<!DOCTYPE html>
<html lang="">
<body>
<div id="myElement"
     style="position: absolute; left: 50px; top: 100px;">
  Hello World
</div>
<script>
  globalThis.setInterval(() => {
    const element = document.getElementById("myElement");
    const rect = element.getBoundingClientRect();
    console.log("X: " + rect.x + ", Y: " + rect.y);
  }, 1000);
</script>
</body>
</html>
```

In this code, we call `getBoundingClientRect()` on an element positioned manually at (50,100). This returns a rectangle object, whose properties are the `x` and `y` coordinates we need. The interval timer will write a new value to the console every second.

The `DOMRect` object provides the following properties for your element: `left`, `top`, `right`, `bottom`, `x`, `y`, `width`, and `height`.

Although you can set negative values in CSS, `getBoundingClientRect()` always returns positive width and height values. The `left` and `x` values are the same, as are the `top` and `y` values — as long as no CSS transform has been applied to the element (more on that later).

The height and width values include the element's border and padding, but **not** its margin value. To calculate the full height of an element you need to access its CSS:

```js
let style = getComputedStyle(element);
let marginTop = parseFloat(style.marginTop);
let marginBottom = parseFloat(style.marginBottom);
```

### Get the Page Coordinate

Using `getBoundingClientRect()`, the position of the `div` will change whenever you scroll on the page. If you want to get the absolute position of the element on the page, not relative to the window, add the number of scrolled pixels to the element's window location using `scrollY`:

```js
console.log("X: " + (rect.x + globalThis.scrollX) + ", Y: " + (rect.y + globalThis.scrollY));
```

The parentheses around the sums are added for JavaScript to treat them as numbers and not concatenate them as strings.

### Handle Other Complexities

If you have a complex page layout, such as one with containers with their own scroll windows (`div` with `overflow: scroll`), or one using CSS transformations, you may need to use other element properties to calculate the `x` and `y` positions.

First, define what the position of an element means in your layout. Is it relative to the page, the window, or another element on the page? It's likely you still need only the window position of the element to position another element next to it.

The following properties of an element may be useful to you (all are in pixels):

- `offsetParent` — The closest positioned ancestor element that is not `static` (the default positioning type).
- `offsetLeft` and `offsetTop` — The distance from the outer border of the current element (including its margin) to the padding edge of the offsetParent.
- `scrollHeight` — The total height of a scrollable element, including the children not visible in the current view that you have to scroll down to see.
- `scrollTop` — The distance from the top of a scrollable element that the user has scrolled down to. If the scrollbar is still at the top of the element then `scrollTop` is 0.
- `clientHeight` — The height of a scrollable element visible on the page.

The `getBoundingClientRect().height` property of an element is different from its `clientHeight`. The `clientHeight` property includes the content and its padding but not its border, margin, or horizontal scrollbar. The `getBoundingClientRect().height` property includes the height of the content, padding, scrollbar, and borders, but not the margin.

You can loop through every `offsetParent` of an element until you return to the HTML body. If you sum all the `offsetTop` values along the way, you'll have the total distance of the element from the start of the page. This will equal `rect.y + globalThis.scrollY` from earlier.

#### CSS Transforms

A transform is a CSS setting like `transform: translate(5px, 6px);`. A transform changes the position of an element visually, but not its original layout position in the document flow.

If an element has been moved with a transform, then `getBoundingClientRect()` will return `left` and `top` values from **before** the translation, and `x` and `y` values from **after** the translation — where the element appears to be visually. So you probably want to use the `x` and `y` values.

If you need to access the exact values of a transform, you can use `getComputedStyle()`:

```js
const transform = window.getComputedStyle(element).getPropertyValue('transform');
if (transform !== 'none') {
  const matrixValues = transform.match(/matrix.*\((.+)\)/)[1].split(', ');
  const tx = parseFloat(matrixValues[4]);
  const ty = parseFloat(matrixValues[5]);
  console.log('Shifted x by ' + tx);
  console.log('Shifted y by ' + ty);
}
```

The `transform` object will be a string, like `matrix(1, 0, 0, 1, 5, 6)`, so we need to extract its values using a regex match. The last two values are the `x` and `y` translation values. If you are using a 3D transformation with `matrix3d`, you need to adjust the regex.

A CSS transform also might involve scaling, rotation, and shearing, which will affect the visual appearance of the element in the window, but not its starting position.

---

*Source: [sentry.io/answers/how-do-i-get-the-position-x-y-of-an-html-element/](https://sentry.io/answers/how-do-i-get-the-position-x-y-of-an-html-element/)*
