ResizeObserver watches element-size changes rather than window resizing. If its callback changes layout, the next calculation may change an observed size and trigger more notifications. The CSS Working Group draft defines the observed boxes and notification-delivery rules discussed below, while MDN and Chrome Developers add implementation context.

Conceptual diagram of a callback changing an observed element and causing another size notification

Conceptual illustration, not browser measurement evidence.

Observation box and reported sizes

The box option to observe(target, {box}) selects which CSS box’s changes trigger observation. ResizeObserverEntry exposes contentBoxSize, borderBoxSize, and devicePixelContentBoxSize as separate values. Their inlineSize and blockSize follow logical writing axes; they are not universally physical width and height. The sequence shape supports fragmentation, but do not assume it always contains multiple entries. Treat contentRect as the legacy physical-axis representation.

Why callback writes can loop

If a callback changes width and that affects the observed box, layout runs again and can produce another notification. The delivery process limits repeated notifications during an update; skipped observations can be deferred and reported as a ResizeObserver loop error. Hiding the error does not remove the layout dependency that caused it.

Make updates converge

Avoid unconditional measurement-write cycles. Compare the desired size with the last applied value and skip redundant writes. A guard is a practical example, not proof that coupled parent-child sizing will stabilize. If each element continually determines the other’s size, the layout can oscillate across frames. Deferring writes with requestAnimationFrame does not remove that feedback relationship.

Read the intended box and clean up

Confirm that you observe the content box or border box the component actually uses. Account for writing mode and box-sizing. Device-pixel content sizes serve pixel-level needs but do not necessarily equal CSS-pixel values. Call unobserve or disconnect when a target or component is removed. ResizeObserver reports element-size changes; it is not a general detector for CSS transforms or every visual difference.

Isolate the source of a loop

Record what the callback reads and which CSS properties it writes. Find the write that changes the next observed size. For example, reading a content width and then widening its parent can change a child’s wrapping and height, making the two elements affect each other. If no script calculation is required, CSS grid, flexbox, or container queries may express the relationship more directly. ResizeObserver is not a reason to poll layout every frame.

A notification deferred to a later rendering opportunity after one loop warning differs from an application that reverses size on every frame. Disconnecting the observer to silence a log can hide evidence without fixing the dependency. Bound the desired size, skip identical writes, and verify that the selected observation box matches the content or border box used by the component.

A hypothetical size trace to find self-referential writes

Consider an explanatory trace, not an execution result. Assume horizontal writing, content-box, no padding or border, and an initial observed content width of 320px. If the callback reads inlineSize, adds 1px, and writes that value back as the same element’s CSS width, later observations can become 321px and then 322px. These are hypothetical inputs and arithmetic outputs, not browser measurements. The key issue is that the callback changes the same observed box it reads, so the rule has no stable target.

For a real diagnosis, record the value read by the callback, the observed box, the CSS property written, and the target before and after each write. This helps isolate the feedback edge. Skipping identical writes can reduce redundant updates, but it cannot make a rule that changes its target by 1px each time converge. Where possible, derive the target from a stable parent constraint rather than the observed element itself. If CSS can express the layout, use grid, flexbox, or a container query. The Resize Observer draft’s depth limit and undelivered-notification error constrain delivery; they do not repair an application’s feedback relationship.

Sources