Start · Sprachen · JavaScript · Referenz · Element.getClientRects()

Element.getClientRects()

Methode

Gibt eine <code>DOMRectList</code> mit je einem <code>DOMRect</code> pro CSS-Border-Box eines Elements zurück, relativ zum Viewport.

seit JavaScript Baseline: alle Browser Kategorie: webapi

Signatur

Element.prototype.getClientRects()

Beschreibung

getClientRects() liefert die Rechtecke aller Border-Boxen, die ein Element beim Rendern erzeugt. Bei den meisten Block-Elementen ist das genau ein Rechteck. Inline-Elemente wie <span> oder <a>, die über mehrere Zeilen umbrechen, erzeugen dagegen ein Rechteck pro Zeilenfragment. Das passiert auch bei Elementen, die über mehrere Spalten oder Seiten verteilt sind.

Die Koordinaten (x, y, top, left, right, bottom, width, height) beziehen sich auf den Viewport, also den sichtbaren Bereich des Fensters. Sie ändern sich beim Scrollen. Für Dokumentkoordinaten addiert man window.scrollX bzw. window.scrollY.

Typische Einsatzfälle sind: Markierungen oder Tooltips an genau der Zeile eines umbrochenen Links platzieren, Textauswahlen hervorheben und die tatsächlich gerenderte Geometrie von Inline-Inhalten messen. Wenn du nur das umschließende Gesamtrechteck brauchst, ist getBoundingClientRect() einfacher. Es gibt die Vereinigung aller Rechtecke aus getClientRects() zurück.

Rückgabewert

Typ
DOMRectList
Beschreibung
Eine listenartige, nicht live aktualisierte Sammlung von DOMRect-Objekten, eines pro Border-Box. Die Liste ist leer, wenn das Element keine Box erzeugt (z. B. display: none oder nicht im Dokument eingehängt).

Beispiele

Zeilenfragmente eines umbrochenen Links zählen

// HTML: <p style="width:150px"><a id="link" href="#">Ein ziemlich langer Linktext, der umbricht</a></p>
const link = document.getElementById('link');
const rects = link.getClientRects();

console.log(`Anzahl Zeilen: ${rects.length}`);
for (const rect of rects) {
  console.log(`top=${Math.round(rect.top)} left=${Math.round(rect.left)} breite=${Math.round(rect.width)}`);
}
Anzahl Zeilen: 3 top=16 left=8 breite=142 top=34 left=8 breite=138 top=52 left=8 breite=64

Jede Zeile eines Inline-Elements hervorheben

const highlightLines = (element) => {
  // Alte Markierungen entfernen
  document.querySelectorAll('.line-marker').forEach((m) => m.remove());

  for (const rect of element.getClientRects()) {
    const marker = document.createElement('div');
    marker.className = 'line-marker';
    Object.assign(marker.style, {
      position: 'absolute',
      // Viewport- in Dokumentkoordinaten umrechnen
      top: `${rect.top + window.scrollY}px`,
      left: `${rect.left + window.scrollX}px`,
      width: `${rect.width}px`,
      height: `${rect.height}px`,
      background: 'rgba(255, 220, 0, 0.4)',
      pointerEvents: 'none'
    });
    document.body.append(marker);
  }
};

highlightLines(document.querySelector('p span.wichtig'));

Tooltip am letzten Zeilenfragment ausrichten

const showTooltipAtEnd = (anchor, text) => {
  const rects = anchor.getClientRects();
  if (rects.length === 0) return; // Element nicht gerendert

  const last = rects[rects.length - 1];
  const tip = document.createElement('div');
  tip.textContent = text;
  tip.style.position = 'fixed'; // fixed => Viewport-Koordinaten direkt nutzbar
  tip.style.top = `${last.bottom + 4}px`;
  tip.style.left = `${last.right}px`;
  document.body.append(tip);
};

showTooltipAtEnd(document.querySelector('a.mehr'), 'Weiterlesen');

Vergleich mit getBoundingClientRect()

const span = document.querySelector('span');
const rects = [...span.getClientRects()];
const bounding = span.getBoundingClientRect();

const unionLeft = Math.min(...rects.map((r) => r.left));
console.log(rects.length, unionLeft === bounding.left);
2 true

// Wichtig · Fallstricke

  • Viewport-relativ: Die Werte ändern sich beim Scrollen. Für absolute Positionierung musst du window.scrollX/scrollY addieren. Für position: fixed kannst du sie direkt verwenden.
  • Kein Array: DOMRectList hat weder map noch filter. Wandle sie vorher mit [...rects] oder Array.from(rects) um. Die Liste ist eine Momentaufnahme und aktualisiert sich nicht von selbst.
  • Leere Liste: Bei display: none, nicht eingehängten Elementen und Elementen ohne Layout-Box ist length gleich 0. Prüfe das vor dem Zugriff auf rects[0].
  • Tabellen: Bei Tabellen-Elementen mit Beschriftung (<caption>) enthält die Liste auch die Box der Beschriftung.
  • Transformationen: CSS-transform wird berücksichtigt. Die Rechtecke sind dann die achsenparallelen Hüllen der transformierten Boxen.
  • Performance: Der Aufruf erzwingt ein synchrones Layout (Reflow). Vermeide es, in Schleifen abwechselnd DOM-Änderungen zu schreiben und Rechtecke zu lesen („Layout Thrashing“).
  • Kompatibilität: Wird von allen modernen Browsern unterstützt. Ältere Versionen des Internet Explorer lieferten abweichende Werte (z. B. ohne width/height).