Signatur
Beschreibung
Der Konstruktor ResizeObserver() erzeugt einen Beobachter, der bei Größenänderungen der beobachteten Elemente die übergebene Callback-Funktion aufruft. Anders als das resize-Event von window reagiert er auf Änderungen einzelner Elemente – egal ob sie durch Fenstergröße, CSS, Inhaltsänderungen, Animationen oder Layout-Verschiebungen ausgelöst werden.
Der Konstruktor selbst beobachtet noch nichts. Erst mit observe(element, options) wird ein Element registriert; mit unobserve() bzw. disconnect() endet die Beobachtung. Die Callback-Funktion erhält ein Array von ResizeObserverEntry-Objekten sowie den Beobachter selbst.
Typische Einsatzfälle sind Container Queries in JavaScript, responsive Diagramme und Canvas-Elemente, virtuelle Listen, automatisch wachsende Textfelder oder das Nachführen von Tooltips und Overlays. Die Meldungen erfolgen gebündelt nach dem Layout und vor dem Zeichnen des Frames – dadurch sind sie effizienter als Polling mit getBoundingClientRect().
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $callback Pflicht | (entries: ResizeObserverEntry[], observer: ResizeObserver) => void | Funktion, die bei Größenänderungen aufgerufen wird. entries enthält pro geändertem Element einen Eintrag mit target, contentRect, contentBoxSize, borderBoxSize und devicePixelContentBoxSize; observer ist die Instanz selbst. |
Rückgabewert
ResizeObserver-Instanz mit den Methoden observe(), unobserve() und disconnect().Beispiele
Grundlegende Nutzung: Größe eines Elements protokollieren
const box = document.querySelector('#box');
const observer = new ResizeObserver((entries) => {
for (const entry of entries) {
const { inlineSize, blockSize } = entry.contentBoxSize[0];
console.log(`Breite: ${Math.round(inlineSize)}px, Höhe: ${Math.round(blockSize)}px`);
}
});
observer.observe(box);
Container-Query in JavaScript: Layout-Klasse je nach Breite
const card = document.querySelector('.card');
const ro = new ResizeObserver(([entry]) => {
const width = entry.borderBoxSize[0].inlineSize;
entry.target.classList.toggle('card--compact', width < 400);
entry.target.classList.toggle('card--wide', width >= 800);
});
// border-box beobachten statt der Standard-content-box
ro.observe(card, { box: 'border-box' });
Canvas scharf halten mit devicePixelContentBoxSize
const canvas = document.querySelector('canvas');
const ctx = canvas.getContext('2d');
const ro = new ResizeObserver(([entry]) => {
const size = entry.devicePixelContentBoxSize?.[0];
const w = size ? size.inlineSize : Math.round(entry.contentRect.width * devicePixelRatio);
const h = size ? size.blockSize : Math.round(entry.contentRect.height * devicePixelRatio);
canvas.width = w;
canvas.height = h;
ctx.fillStyle = 'teal';
ctx.fillRect(0, 0, w / 2, h / 2);
});
try {
ro.observe(canvas, { box: 'device-pixel-content-box' });
} catch {
ro.observe(canvas); // Fallback, z. B. für Safari
}
Aufräumen: Beobachtung beenden
const panel = document.querySelector('#panel');
let count = 0;
const ro = new ResizeObserver((entries, observer) => {
count++;
console.log(`Änderung Nr. ${count}`);
if (count >= 3) {
observer.unobserve(panel); // nur dieses Element
console.log('Beobachtung beendet');
}
});
ro.observe(panel);
// Beim Entfernen einer Komponente alles lösen:
// ro.disconnect();
// Wichtig · Fallstricke
- Endlosschleifen: Wenn die Callback-Funktion die Größe des beobachteten Elements selbst ändert, kann das Fehler wie
ResizeObserver loop completed with undelivered notificationsauslösen. Das ist meist harmlos, deutet aber auf eine Rückkopplung hin. Abhilfe: Änderungen perrequestAnimationFrame()verzögern oder nur bei tatsächlicher Abweichung schreiben. - Erster Aufruf: Direkt nach
observe()wird der Callback einmal mit der Anfangsgröße aufgerufen – auch ohne tatsächliche Änderung (außer das Element hat die Größe 0×0 und ist nicht gerendert). - Ohne
newaufgerufen wirftResizeObserver()einenTypeError; ebenso, wenncallbackkeine Funktion ist. contentBoxSizeundborderBoxSizesind Arrays (wegen mehrspaltiger Fragmente); ältere Browser lieferten ein einzelnes Objekt.contentRectgilt als Altlast, ist aber am breitesten unterstützt.device-pixel-content-boxwird in Safari nicht unterstützt – dortobserve()intry/catchabsichern.- Speicherlecks vermeiden: In SPA-Komponenten beim Unmount
disconnect()aufrufen. - Kompatibilität: Chrome 64+, Firefox 69+, Safari 13.1+, Edge 79+. Nicht in Node.js verfügbar (für Tests ggf. Polyfill/Mock in jsdom nötig).