Rooks
HooksUI & Layout

useBoundingclientrect

Reads an element's DOMRect after mount and whenever the observed DOM subtree mutates.

About

useBoundingclientrect calls getBoundingClientRect() for an element held in an existing object ref. It measures once after mount and again when MutationObserver reports attribute, text, or child-list changes in that element's subtree.

Example

import { useRef, useState } from "react";
import { useBoundingclientrect } from "rooks";

export default function MeasuredCard() {
  const targetRef = useRef<HTMLDivElement | null>(null);
  const [wide, setWide] = useState(false);
  const rect = useBoundingclientrect(targetRef);

  return (
    <section>
      <div
        ref={targetRef}
        style={{ width: wide ? 320 : 180, padding: 12, border: "1px solid" }}
      >
        This element is{" "}
        {rect ? `${Math.round(rect.width)}px wide` : "being measured"}.
      </div>
      <button type="button" onClick={() => setWide((value) => !value)}>
        Change width
      </button>
    </section>
  );
}

Parameters

ParameterTypeDescription
refMutableRefObject<HTMLElement | null>Object ref containing the element to measure.

Return value

Returns the element's DOMRect, including its viewport-relative position and dimensions, or null before measurement and whenever the ref has no current element.

Behavior and lifecycle

The initial measurement runs after mount. The hook then creates a MutationObserver with attributes, characterData, childList, and subtree all enabled. Each mutation rereads the full bounding rect. The observer disconnects when its effect is replaced or the component unmounts.

Resize and scroll events do not themselves trigger this hook. A layout shift without a DOM mutation can therefore leave the returned rect stale; use useDimensionsRef, useMeasure, or an explicit resize observer when that distinction matters.

Compatibility and accessibility

Server rendering returns null when the ref is empty; DOM measurement and observer creation happen in client effects. A browser without MutationObserver needs a polyfill before an element is observed. Measuring layout can force browser layout work, so avoid mutation-heavy targets.

The hook does not change semantics or focus. Use the measurement to enhance layout without removing essential content or controls at zoomed or reflowed sizes. See SSR and browser APIs.

On this page