Signatur
Beschreibung
Range.getBoundingClientRect() berechnet das kleinste Rechteck, das alle Rahmenrechtecke des Bereichsinhalts einschließt. Das entspricht der Vereinigung aller Rechtecke, die Range.getClientRects() liefert. Die Koordinaten beziehen sich wie bei Element.getBoundingClientRect() auf den sichtbaren Viewport. Die Scroll-Position ist also schon eingerechnet.
Die Methode ist vor allem dann nützlich, wenn nicht ein ganzes Element, sondern ein Textausschnitt vermessen werden soll. Typische Beispiele sind eine schwebende Werkzeugleiste über markiertem Text, Tooltips an einzelnen Wörtern, die Position des Textcursors in eigenen Editoren oder das Messen der Breite eines Teilstrings.
Ist der Bereich eingeklappt (collapsed), gibt die Methode ein Rechteck mit der Breite 0 an der Position der Einfügemarke zurück, sofern der Browser diese Position bestimmen kann. Für mehrzeilige Auswahlen ist das Ergebnis ein großes, umschließendes Rechteck. Wer die einzelnen Zeilen braucht, verwendet getClientRects().
Rückgabewert
DOMRect mit den Eigenschaften x, y, width, height, top, right, bottom und left in CSS-Pixeln, relativ zum Viewport. Bei einem leeren oder nicht dargestellten Bereich sind alle Werte 0.Beispiele
Werkzeugleiste über markiertem Text positionieren
const toolbar = document.querySelector('#toolbar');
document.addEventListener('selectionchange', () => {
const selection = window.getSelection();
if (!selection || selection.rangeCount === 0 || selection.isCollapsed) {
toolbar.hidden = true;
return;
}
const rect = selection.getRangeAt(0).getBoundingClientRect();
// Viewport-Koordinaten in Dokument-Koordinaten umrechnen
toolbar.style.left = `${rect.left + window.scrollX + rect.width / 2}px`;
toolbar.style.top = `${rect.top + window.scrollY - toolbar.offsetHeight - 8}px`;
toolbar.hidden = false;
});
Breite eines Teilstrings in einem Absatz messen
// <p id="satz">Hallo schöne Welt</p>
const textNode = document.querySelector('#satz').firstChild;
const range = document.createRange();
range.setStart(textNode, 6); // "schöne"
range.setEnd(textNode, 12);
const { width, height, left } = range.getBoundingClientRect();
console.log(`Breite: ${width.toFixed(1)}px, Höhe: ${height}px, links: ${left}px`);
Position der Einfügemarke (Caret) ermitteln
const getCaretRect = () => {
const sel = window.getSelection();
if (!sel || sel.rangeCount === 0) return null;
const range = sel.getRangeAt(0).cloneRange();
range.collapse(true);
const rect = range.getBoundingClientRect();
// Fallback: eingeklappte Ranges am Zeilenanfang liefern oft nur Nullen
if (rect.width === 0 && rect.height === 0 && rect.top === 0) {
return range.getClientRects()[0] ?? null;
}
return rect;
};
document.querySelector('[contenteditable]').addEventListener('keyup', () => {
console.log(getCaretRect());
});
// Wichtig · Fallstricke
- Viewport-Koordinaten: Die Werte ändern sich beim Scrollen. Für absolute Positionierung im Dokument addierst du
window.scrollXundwindow.scrollY. - Eingeklappte Bereiche: Steht der Bereich zum Beispiel direkt an einer Elementgrenze oder in einem leeren Element, liefern manche Browser ein Rechteck, in dem alle Werte 0 sind. Prüfe das und nutze notfalls einen Ausweichweg, etwa
getClientRects()oder ein vorübergehend eingefügtes Hilfselement. - Mehrzeilige Bereiche: Das Rechteck umschließt alle Zeilen und kann dadurch große leere Flächen enthalten. Für zeilengenaue Hervorhebungen verwendest du
getClientRects(). - Performance: Der Aufruf erzwingt eine synchrone Layout-Berechnung (Reflow). Rufe die Methode nicht in engen Schleifen auf, in denen du gleichzeitig das DOM veränderst. Wenn möglich, fasse die Aufrufe mit
requestAnimationFramezusammen. - Transformationen wie
transform: scale()und das Zoomen der Seite fließen in das Ergebnis ein. Elemente mitdisplay: noneliefern keine Rechtecke. - Die Methode stammt aus der Spezifikation CSSOM View. Sehr alte Browser, etwa den Internet Explorer vor Version 9, unterstützen sie nicht.
StaticRangebietet die Methode nicht an.