JavaScript Element getClientRects() Method

Beginner
⏱️ 12 min read
📚 Updated: Jul 2026
🎯 5 Examples
🚀 5 Try-it labs
Baseline
Instance method

What You’ll Learn

Element.getClientRects() is an instance method that returns a collection of DOMRect objects—one per CSS border box. Learn multiline inline text, how it compares to getBoundingClientRect(), looping rects, and five try-it labs aligned with MDN.

01

Kind

Instance method

02

Returns

DOMRectList

03

Args

None

04

Per line

Inline wraps

05

vs getBCR

Many vs union

06

Status

Baseline widely

Introduction

Most elements have one border box, so one rectangle is enough. But when text wraps inside an inline element like <span>, each line gets its own border box. getClientRects() exposes every one of those boxes.

The return value is a DOMRectList you can loop with for...of or index like an array. Each DOMRect has top, left, width, and height relative to the viewport.

💡
Beginner tip

Need one overall box? Use getBoundingClientRect() instead—MDN describes it as the union of all client rects. Use getClientRects() when you need per-line or per-fragment positions.

This page is part of JavaScript Element. Pair it with getBoundingClientRect() for the single-rectangle shortcut.

Understanding the getClientRects() Method

Calling el.getClientRects() collects every CSS border box for the element and returns them as a list of DOMRect objects.

  • It is an instance method on Element.
  • Takes no parameters (MDN).
  • Returns a DOMRectList (array-like collection).
  • Multiline inline elements often return multiple rects.
  • display:none and non-rendered elements return an empty list.
  • Scrolling updates coordinates, same as getBoundingClientRect().

📝 Syntax

General form of Element.getClientRects (MDN):

JavaScript
getClientRects()

Parameters

None.

Return value

A collection of DOMRect objects—one per CSS border box. Each rect’s top and left are relative to the viewport. MDN notes fractional pixel offsets are possible.

Common patterns

JavaScript
const rects = element.getClientRects();

console.log(rects.length);

for (const rect of rects) {
  console.log(rect.top, rect.left, rect.width, rect.height);
}

// First line only:
if (rects.length > 0) {
  console.log(rects[0]);
}

⚡ Quick Reference

GoalCode
All border boxesel.getClientRects()
Count rectsrects.length
Loop rectsfor (const r of rects)
Single union boxel.getBoundingClientRect()
Hidden elementEmpty list (length === 0)
MDN statusBaseline Widely available (since July 2015)

🔍 At a Glance

Four facts to remember about Element.getClientRects().

Returns
DOMRectList

Many boxes

Baseline
widely

Since July 2015

Inline
per line

Wrapped text

Union
getBCR

One rect

📋 Client rect APIs

getClientRects()getBoundingClientRect()offsetWidth
ReturnsDOMRectList (multiple)Single DOMRectNumber (width only)
Wrapped inline textOne rect per lineUnion of all linesTotal width (one number)
Position dataYes (per rect)Yes (one box)No
Best forPer-line highlights, text selection UITooltips, overall boxQuick size check
display:noneEmpty listZero-size rect0

Examples Gallery

Examples follow MDN Element.getClientRects() patterns. Use View Output or Try It Yourself for each case.

📚 Getting Started

MDN: a multiline <span> returns multiple rects; a <p> usually returns one.

Example 1 — Multiline <span> vs <p>

Wrapped inline text gets one border box per line.

JavaScript
const span = document.querySelector("p span");
const paragraph = document.querySelector("p");

console.log(span.getClientRects().length);       // often > 1
console.log(paragraph.getClientRects().length); // usually 1
Try It Yourself

How It Works

MDN: inline-level elements that wrap across lines have a border box around each line. Block paragraphs typically have a single border box.

Example 2 — Loop Through All Rects

Read top, left, width, and height for each box.

JavaScript
const rects = element.getClientRects();

for (const rect of rects) {
  console.log({
    top: rect.top,
    left: rect.left,
    width: rect.width,
    height: rect.height
  });
}
Try It Yourself

How It Works

DOMRectList is array-like. Use for...of or index with rects[i] to process each fragment.

📈 Practical Patterns

Union vs multiple boxes, list items, and hidden elements.

Example 3 — vs getBoundingClientRect()

Many client rects vs one union rectangle.

JavaScript
const span = document.querySelector("span");

const rects = span.getClientRects();
const union = span.getBoundingClientRect();

console.log(rects.length);     // e.g. 3 lines
console.log(union.width);      // spans full wrapped width
console.log(union.height);     // total height of all lines
Try It Yourself

How It Works

MDN: getBoundingClientRect() is the union of all client rects. Use getClientRects() when you need each line separately.

Example 4 — One Rect per <li>

MDN list example: each list item has its own border box.

JavaScript
const items = document.querySelectorAll("ol li");

items.forEach((li, i) => {
  const rect = li.getClientRects()[0];
  console.log(`Item ${i + 1}:`, rect.top, rect.height);
});
Try It Yourself

How It Works

MDN notes list marker numbers are outside the border box, so client rects match the content box area of each li, not the bullet number.

Example 5 — display:none Returns Empty

Non-rendered elements return an empty DOMRectList.

JavaScript
const hidden = document.querySelector(".hidden-box");
const visible = document.querySelector(".visible-box");

console.log(hidden.getClientRects().length);  // 0
console.log(visible.getClientRects().length); // 1 or more
Try It Yourself

How It Works

MDN: for display:none and elements not directly rendered, an empty list is returned. Always check length before reading rects[0].

🚀 Common Use Cases

  • Highlighting each line of wrapped inline text in a rich editor.
  • Text-selection UI that draws overlays per line fragment.
  • Measuring individual list items or table rows for animations.
  • Building custom caret or range indicators across multiple boxes.
  • Debugging layout when one element spans unexpected fragments.
  • Choosing per-line vs union measurements before calling getBoundingClientRect().

🧠 How getClientRects() Collects Border Boxes

1

Call with no arguments

element.getClientRects()

Invoke
2

Find every border box

Browser collects one box per line fragment (inline) or a single box (block).

Layout
3

Return DOMRectList

Each DOMRect has viewport-relative top, left, width, height.

Result
4

Loop or union

Process each rect, or use getBoundingClientRect() for one combined box.

📝 Notes

  • Not Deprecated, Experimental, or Non-standard on MDN (Baseline Widely available, July 2015).
  • Returns a DOMRectList, not a single DOMRect.
  • Multiline inline elements often return multiple rectangles.
  • display:none returns an empty list (MDN).
  • Table captions may be included in table client rects (MDN).
  • Related: getBoundingClientRect(), checkVisibility(), JavaScript hub.

Browser Support

Element.getClientRects() is Baseline Widely available (MDN: across browsers since July 2015). Logos use the shared browser-image-sprite.png sprite from this project.

Baseline Widely available

Element.getClientRects()

Get every CSS border box as DOMRect objects — essential for multiline inline text and per-fragment layout.

Baseline Widely available
Google Chrome Supported · Desktop & Mobile
Yes
Microsoft Edge Supported · Chromium
Yes
Mozilla Firefox Supported · Desktop & Mobile
Yes
Apple Safari Supported · macOS & iOS
Yes
Opera Supported · Modern versions
Yes
Internet Explorer Supported in legacy IE
Yes
getClientRects() Excellent

Bottom line: Use getClientRects() when you need one rectangle per line or fragment. Prefer getBoundingClientRect() when a single union box is enough.

Conclusion

Element.getClientRects() returns every CSS border box for an element as a DOMRectList—the right tool when wrapped inline text needs per-line measurements.

Continue with getBoundingClientRect(), checkVisibility(), shadowRoot, or the JavaScript hub.

💡 Best Practices

✅ Do

  • Check rects.length before reading rects[0]
  • Use for...of to process every line fragment
  • Prefer getBoundingClientRect() for one overall box
  • Re-read on scroll/resize when drawing overlays
  • Handle empty lists for display:none elements

❌ Don’t

  • Assume exactly one rect for wrapped inline text
  • Confuse DOMRectList with a plain array (mostly fine with for...of)
  • Use for margin measurements (margin is outside the box)
  • Expect child overflow to expand parent rects (MDN)
  • Call excessively inside tight loops without throttling

Key Takeaways

Knowledge Unlocked

Five things to remember about Element.getClientRects()

Multiple border boxes per element.

5
Core concepts
📄 02

Inline

per line

Wrap
✍️ 03

Union

getBCR

One box
04

Hidden

length 0

Empty
05

Baseline

widely available

Status

❓ Frequently Asked Questions

It returns a collection of DOMRect objects—one for each CSS border box associated with the element. Each rect describes size and viewport-relative position in pixels.
No. MDN marks Element.getClientRects() as Baseline Widely available (across browsers since July 2015). It is not Deprecated, Experimental, or Non-standard.
getClientRects() returns every border box (multiple for wrapped inline text). getBoundingClientRect() returns one DOMRect that is the union of all those boxes.
MDN: inline-level elements like a span that wraps across lines get one border box per line. A block-level paragraph usually has only one.
An empty list (length 0). MDN: elements that are not directly rendered, including display:none, return no rectangles.
Yes. Coordinates are viewport-relative and change when you scroll, same as getBoundingClientRect(). Add scroll offsets for document coordinates.
Did you know?

MDN notes that most elements have one border box, but multiline inline-level elements (like a wrapping <span>) get one per line. That is when getClientRects() shines over a single union rectangle.

More Element Topics

Browse Element methods and properties to keep building your DOM skills.

getBoundingClientRect() →

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

8 people found this page helpful