Rooks
HooksUI & Layout

useMeasure

Measures client, offset, and scroll dimensions with ResizeObserver and optional debouncing.

About

useMeasure observes one element with ResizeObserver and exposes its inner, outer, and scroll dimensions. It is suited to element-size changes; unlike bounding-rect hooks, it does not report viewport position.

Example

import { useMeasure } from "rooks";

export default function SizeReadout() {
  const [panelRef, size] = useMeasure({ debounce: 50 });

  return (
    <section>
      <div
        ref={panelRef}
        style={{
          width: "60%",
          minWidth: 180,
          minHeight: 120,
          overflow: "auto",
          border: "1px solid",
        }}
      >
        Resize the window to change this panel.
      </div>
      <p aria-live="polite">
        Client size: {size.innerWidth} × {size.innerHeight}; offset size:{" "}
        {size.outerWidth} × {size.outerHeight}
      </p>
    </section>
  );
}

Parameters

The optional object has this inline shape; these option and result type names are not exported from the package entrypoint.

OptionTypeDefaultDescription
debouncenumber0Milliseconds to delay trailing measurements. Values above zero use a trailing-only debounce.
disabledbooleanfalseDisconnects or avoids creating the observer. Existing measurements are retained.
onMeasure(measurements) => voidnoneCalled after each completed measurement with the latest dimensions.

The callback is kept fresh through a ref; changing it alone does not recreate the observer.

Return value

Returns [ref, measurements]. The callback ref accepts an HTMLElement. measurements begins with every field set to zero and contains:

FieldDOM source
innerWidth, innerHeightclientWidth, clientHeight
innerScrollWidth, innerScrollHeightscrollWidth, scrollHeight
outerWidth, outerHeightoffsetWidth, offsetHeight
outerScrollWidth, outerScrollHeightscrollWidth, scrollHeight

The two pairs of scroll fields currently report the same DOM values.

Behavior and lifecycle

After a node attaches, the hook observes it with { box: "content-box" } and performs an initial measurement. Resize notifications run immediately or through the configured trailing debounce. Changing the node, disabled, debounce behavior, or measurement function disconnects the old observer; unmount also disconnects it.

When disabled, calls are ignored and the last measurements remain visible. The hook warns and leaves zero or previous values when ResizeObserver is unavailable. Errors thrown by onMeasure are not caught.

Compatibility and accessibility

The initial all-zero snapshot is deterministic during server rendering because observer work runs only in effects. Do not interpret zero as proof that a rendered element has no size during hydration. Older browsers need a ResizeObserver polyfill or a product-level fallback.

Measurements should enhance responsive layout without replacing semantic structure. Test zoom, text enlargement, and content reflow rather than relying on fixed pixel assumptions. See SSR and browser APIs.

On this page