---
title: useElementBounding
description: "Tracks the bounding rect of a DOM element — `x`, `y`, `top`, `right`, `bottom`, `left`, `width`, `height` — as reactive `Observable<number>` values. Uses [ResizeObserver](https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserver) for size changes, [MutationObserver](https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver) for `style`/`class` attribute changes, and `scroll`/`resize` window events for position changes. `requestAnimationFrame` is used by default so CSS transform animations are captured accurately."
category: Elements
type-table:
  import: "@usels/web"
  name: "UseElementBounding"
  params:
    children:
      - UseElementBoundingOptions
---

## Demo

## Usage

<CodeTabs>
  <Fragment slot="hook">
    ```tsx twoslash
    // @noErrors
    import { useRef$ } from "@usels/core";
    import { useElementBounding } from "@usels/web";

    function Component() {
      const el$ = useRef$<HTMLDivElement>();
      const { top$, left$, width$, height$ } = useElementBounding(el$);

      return (
        <div ref={el$}>
          {width$.get()} × {height$.get()} at ({left$.get()}, {top$.get()})
        </div>
      );
    }
    ```

  </Fragment>
  <Fragment slot="scope">
    ```tsx
    import { createRef$ } from "@usels/core";
    import { createElementBounding } from "@usels/web";

    function Component() {
      "use scope";
      const el$ = createRef$<HTMLDivElement>();
      const { top$, left$, width$, height$ } = createElementBounding(el$);

      return (
        <div ref={el$}>
          {width$.get()} × {height$.get()} at ({left$.get()}, {top$.get()})
        </div>
      );
    }
    ```

  </Fragment>
</CodeTabs>

### Manual update

```tsx
// @noErrors
import { useRef$, Ref$ } from "@usels/core";
import { useElementBounding } from "@usels/web";
declare const el$: Ref$<HTMLDivElement>;
// ---cut---
const { top$, left$, update } = useElementBounding(el$);

// Force-recalculate bounding rect imperatively
update();
```

### Disable window scroll tracking

```typescript
const { top$, left$ } = useElementBounding(el$, { windowScroll: false });
```

### Skip requestAnimationFrame (synchronous reads)

```typescript
const { width$, height$ } = useElementBounding(el$, { useCssTransforms: false });
```

### Keep values on unmount (no reset)

```typescript
const { top$ } = useElementBounding(el$, { reset: false });
```
