ResizeObserver notifies your code when an observed element's size changes — for any reason, not just a browser window resize — enabling responsive component logic that CSS media queries alone cannot express.
1The Resize Observer API | JavaScript Tutorial - In-Depth Guide Part 1
ResizeObserver calls its callback whenever an observed element's size changes, whether due to window resizing, content changes, or CSS/layout updates.
const observer = new ResizeObserver((entries) => {
entries.forEach((entry) => {
console.log('New size:', entry.contentRect.width, entry.contentRect.height);
});
});
observer.observe(document.querySelector('.card'));Reacting to Size Changes
2The Resize Observer API | JavaScript Tutorial - In-Depth Guide Part 2
Each observer entry provides multiple size measurements — contentRect (legacy), plus the newer contentBoxSize and borderBoxSize arrays that distinguish padding/border from content area.
const observer = new ResizeObserver((entries) => {
const { inlineSize, blockSize } = entries[0].contentBoxSize[0];
console.log(inlineSize, blockSize); // width/height, respecting writing mode
});contentBoxSize & borderBoxSize
3The Resize Observer API | JavaScript Tutorial - In-Depth Guide Part 3
ResizeObserver enables 'container query'-style component logic in JavaScript: a component can change its own internal layout based on its own size, not the viewport's.
const observer = new ResizeObserver((entries) => {
const width = entries[0].contentRect.width;
entries[0].target.classList.toggle('compact', width < 300);
});
observer.observe(cardElement);Container Query'-Style Logic
4The Resize Observer API | JavaScript Tutorial - In-Depth Guide Part 4
Be careful not to resize the observed element FROM WITHIN its own resize callback — this creates a feedback loop that browsers detect and report as an error.
// Risky: this can create a resize feedback loop
const observer = new ResizeObserver((entries) => {
entries[0].target.style.width = entries[0].contentRect.width + 10 + 'px';
});Avoiding Feedback Loops
5The Resize Observer API | JavaScript Tutorial - In-Depth Guide Part 5
Like other observer APIs, always disconnect a ResizeObserver when it's no longer needed, such as when a component unmounts, to avoid leaking observation callbacks.
useEffect(() => {
const observer = new ResizeObserver(handleResize);
observer.observe(elementRef.current);
return () => observer.disconnect();
}, []);Cleanup on Unmount
6Step-by-Step Breakdown
ResizeObserver calls its callback whenever an observed element's size changes, whether due to window resizing, content changes, or CSS/layout updates.
Checkpoint: Does ResizeObserver only fire in response to the browser window being resized?
- →Yes, it is equivalent to the window resize event
- →No, it fires for any change to the observed element's size
Each observer entry provides multiple size measurements — contentRect (legacy), plus the newer contentBoxSize and borderBoxSize arrays that distinguish padding/border from content area.
ResizeObserver enables 'container query'-style component logic in JavaScript: a component can change its own internal layout based on its own size, not the viewport's.
Be careful not to resize the observed element FROM WITHIN its own resize callback — this creates a feedback loop that browsers detect and report as an error.
Checkpoint: What can happen if a ResizeObserver callback resizes the very element it is observing?
- →A feedback loop, which browsers detect and report
- →Nothing, this is a completely safe and common pattern
Like other observer APIs, always disconnect a ResizeObserver when it's no longer needed, such as when a component unmounts, to avoid leaking observation callbacks.
Next, we'll explore 'The Mutation Observer'.
Level Up 🚀
Advanced cheat sheets, SEO tricks, and interview prep for this topic.
Browser Support
Fully supported.
Fully supported.
Fully supported.
Fully supported.
Accessibility (A11y)
1Ensure Layout Changes Triggered by ResizeObserver Preserve Focus and Reading Order
When ResizeObserver-driven logic switches a component between layouts (e.g. full vs. compact), verify that keyboard focus is not lost and that the DOM reading order for screen readers remains logical after the layout switch.
SEO Implications
- 1
No Direct SEO Effect
ResizeObserver is a client-side layout-reaction tool; SEO relevance is limited to ensuring responsive component logic doesn't introduce rendering bugs affecting content visibility.
Best Practices
Use ResizeObserver for Component-Level Responsive Logic
When a component's layout needs to adapt to its own available space (not the viewport), ResizeObserver (or native CSS Container Queries, where sufficient) is the correct tool, rather than trying to infer this from window resize events.
Always Disconnect Observers in Cleanup Functions
Just like event listeners, a ResizeObserver tied to a removed element should be disconnected to avoid unnecessary callback overhead and potential memory retention.
Frequent Bugs
Writing a ResizeObserver callback that sets a new size on the observed element itself (directly or via a layout side effect), causing a resize feedback loop and a browser console error.
Ensure the callback only reads size information and updates unrelated state (like a CSS class or React state), never directly resizing the same element being observed.
Forgetting to disconnect a ResizeObserver when a component unmounts, leaving the observer active and callbacks firing for a removed element.
Call `observer.disconnect()` in the component's cleanup/unmount logic, mirroring how you would clean up an event listener.
Real-World Examples
A Responsive Card Component That Adapts to Its Container
A reusable card component needed to switch to a compact, icon-only layout whenever it was rendered inside a narrow sidebar, regardless of overall page width.
const observer = new ResizeObserver(([entry]) => {
entry.target.classList.toggle('compact-layout', entry.contentRect.width < 240);
});
observer.observe(cardElement);