Signatur
Beschreibung
ResizeObserver meldet, wenn sich die Abmessungen eines Element (Inhalts- oder Rahmenbereich) oder die Bounding-Box eines SVGElement ändern. Anders als das resize-Event von window reagiert der Observer auf jede Größenänderung eines einzelnen Elements, egal ob sie durch das Ändern der Fenstergröße, per CSS, durch neuen Inhalt, Flex-/Grid-Layout oder JavaScript entsteht.
Typische Einsatzfälle sind komponentenbasierte, responsive Layouts (Element-Queries in JavaScript), das Neuzeichnen von <canvas>-Inhalten oder Diagrammen bei neuer Containergröße, virtuelle Listen, automatisch wachsende Textfelder und das Nachführen von Tooltips oder Overlays.
Der Konstruktor new ResizeObserver(callback) erwartet eine Callback-Funktion, die ein Array von ResizeObserverEntry-Objekten und den Observer selbst erhält. Die Methoden sind:
observe(target, options)– beginnt die Beobachtung eines Elements;options.boxlegt fest, welche Box gemessen wird ("content-box","border-box","device-pixel-content-box").unobserve(target)– beendet die Beobachtung eines bestimmten Elements.disconnect()– beendet die Beobachtung aller Elemente.
Die Callbacks laufen nach dem Layout und vor dem Zeichnen des Frames. Jedes ResizeObserverEntry bietet target, contentRect (älter, DOMRectReadOnly) sowie die moderneren Arrays contentBoxSize, borderBoxSize und devicePixelContentBoxSize mit inlineSize und blockSize.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $callback Pflicht | (entries: ResizeObserverEntry[], observer: ResizeObserver) => void | Wird bei Größenänderungen aufgerufen. Einmal auch direkt nach observe() mit der Anfangsgröße. entries enthält ein Objekt pro Element, dessen Größe sich geändert hat. |
|
| $target Pflicht | Element | SVGElement | Parameter von observe()/unobserve(): das zu beobachtende Element. |
|
| $options.box | "content-box" | "border-box" | "device-pixel-content-box" | "content-box" | Parameter von observe(): Welches Box-Modell gemessen wird. device-pixel-content-box liefert die Größe in echten Gerätepixeln, ideal für Canvas. |
Rückgabewert
ResizeObserver-Instanz. observe(), unobserve() und disconnect() geben undefined zurück.Beispiele
Observer erzeugen und Größe protokollieren
const box = document.querySelector('#panel');
const observer = new ResizeObserver((entries) => {
for (const entry of entries) {
// contentBoxSize ist ein Array (z. B. für mehrspaltige Fragmente)
const { inlineSize, blockSize } = entry.contentBoxSize[0];
console.log(`Breite: ${Math.round(inlineSize)}px, Höhe: ${Math.round(blockSize)}px`);
}
});
observer.observe(box);
Komponente per CSS-Klasse an Containerbreite anpassen
const cards = document.querySelectorAll('.card');
const ro = new ResizeObserver((entries) => {
for (const { target, borderBoxSize } of entries) {
const width = borderBoxSize[0].inlineSize;
target.classList.toggle('card--compact', width < 400);
target.classList.toggle('card--wide', width >= 800);
}
});
cards.forEach((card) => ro.observe(card, { box: 'border-box' }));
Canvas scharf in Gerätepixeln neu zeichnen
const canvas = document.querySelector('canvas');
const ctx = canvas.getContext('2d');
const draw = () => {
ctx.fillStyle = '#0a7';
ctx.fillRect(0, 0, canvas.width, canvas.height / 2);
};
const ro = new ResizeObserver(([entry]) => {
// Fallback, falls device-pixel-content-box nicht unterstützt wird
const size = entry.devicePixelContentBoxSize?.[0];
canvas.width = size ? size.inlineSize : Math.round(entry.contentRect.width * devicePixelRatio);
canvas.height = size ? size.blockSize : Math.round(entry.contentRect.height * devicePixelRatio);
draw();
});
try {
ro.observe(canvas, { box: 'device-pixel-content-box' });
} catch {
ro.observe(canvas);
}
Beobachtung beenden (z. B. beim Entfernen einer Komponente)
const el = document.querySelector('#chart');
const ro = new ResizeObserver(([entry]) => {
console.log('Neue Breite:', entry.contentRect.width);
});
ro.observe(el);
// Später: nur dieses Element nicht mehr beobachten
ro.unobserve(el);
// Oder alle Beobachtungen auf einmal beenden
ro.disconnect();
// Wichtig · Fallstricke
- Endlosschleifen: Wenn Sie im Callback die Größe des beobachteten Elements ändern, wird ein weiterer Durchlauf ausgelöst. Der Browser bricht das ab und meldet
ResizeObserver loop completed with undelivered notifications(bzw.loop limit exceeded) als Fehler anwindow.onerror. Größenänderungen nach Möglichkeit an Kind-Elementen vornehmen oder perrequestAnimationFrameverschieben. - Der Callback wird sofort nach
observe()einmal mit der Anfangsgröße aufgerufen, außerdem wenn ein Element eingefügt, entfernt oder aufdisplay: nonegesetzt wird (Größe 0). - Reine Positionsänderungen oder
transform(z. B.scale()) lösen keine Meldung aus, da sich die Layoutgröße nicht ändert. contentBoxSize/borderBoxSizesind Arrays; ältere Firefox-Versionen (vor 92) lieferten ein einzelnes Objekt.contentRectist aus Kompatibilitätsgründen noch vorhanden, gilt aber als veraltet.device-pixel-content-boxwird von Safari erst seit Version 17 unterstützt – ggf. mittry/catchabsichern.inlineSize/blockSizehängen vom Schreibmodus ab: bei vertikaler Schrift entsprichtinlineSizeder Höhe.- Für die Performance ist ein einziger Observer für viele Elemente günstiger als viele einzelne Instanzen. Nicht mehr benötigte Observer mit
disconnect()beenden, um Speicherlecks in SPAs zu vermeiden. - Für reine Layout-Anpassungen ohne JavaScript sind CSS-Container-Queries (
@container) oft die bessere Wahl.