The resize event only tells you when the window changes size. ResizeObserver tells you when any element changes size, whether because the window changed, content loaded, or something else resized it. That makes it ideal for components that adapt to their own width.
<style>
#box { resize: horizontal; overflow: auto; width: 240px; min-width: 100px; max-width: 100%; border: 2px solid #1a5276; padding: 8px; }
</style>
<div id="box">Drag my bottom-right corner to resize me.</div>
<p id="out"></p>
<script>
const box = document.querySelector("#box");
const out = document.querySelector("#out");
const observer = new ResizeObserver(entries => {
for (const entry of entries) {
const width = Math.round(entry.contentRect.width);
out.textContent = `Width: ${width}px`;
entry.target.style.background = width < 200 ? "#fdebd9" : "#d0e8f2";
}
});
observer.observe(box);
</script>
The callback runs once at the start, and again whenever the size changes.
The entry
| Property | Meaning |
|---|---|
entry.target | the element |
entry.contentRect | its content box size and position |
entry.contentBoxSize, borderBoxSize | newer, more precise sizes |
Practical uses
- Component-level responsiveness: switch a card’s layout when the card is narrow, not when the window is.
- Canvas or chart elements that must redraw to fit their container.
- Truncating text or reflowing a toolbar to fit.
- Sticky layouts that depend on a header whose height changes.
For simple layout changes, prefer CSS container queries, which do this in CSS with no JavaScript.
.card-wrapper { container-type: inline-size; }
@container (min-width: 400px) {
.card { display: flex; }
}
Use ResizeObserver when you need the size in JavaScript (for a canvas, or calculations).
Avoid the infinite loop
If your callback changes the observed element’s size, it triggers itself again. The browser stops with an error message (“ResizeObserver loop completed with undelivered notifications”). Change something that does not resize the element, or observe a parent.
Stop watching
observer.unobserve(box); // one element
observer.disconnect(); // everything
Disconnect when a component is removed.
Window resize still has its place
For window-wide things like reading window.innerWidth, the resize event is fine. Throttle it if the work is heavy (Debouncing and Throttling).
Pair it with a clean-up
disconnect() when it is removed, so you do not leave observers running.