ResizeObserver fires whenever an element's box changes size, whatever the cause. Entries carry contentBoxSize and borderBoxSize arrays.
<div id="card" style="width: 200px; padding: 10px; border: 2px solid #1565c0">Card</div>
<pre id="out" style="font: 14px/1.5 monospace; margin: 8px 0 0"></pre>
<script>
new ResizeObserver(([{ target, contentBoxSize: [box], borderBoxSize: [border] }]) => {
target.textContent = box.inlineSize < 300 ? 'Compact card' : 'Wide card with details';
out.textContent += `content ${box.inlineSize}px, border box ${border.inlineSize}px\n`;
}).observe(card);
requestAnimationFrame(() => requestAnimationFrame(() => { card.style.width = '320px'; }));
</script>
The width changes one frame later, as when a sidebar collapses. Use container queries (CSS Debugging and Tooling) for pure styling. Resizing the target inside the callback raises "ResizeObserver loop completed with undelivered notifications".