revision:
The getClientRects() method of the Element interface returns a collection of DOMRect objects that indicate the bounding rectangles for each CSS border box in a client.
Most elements only have one border box each, but a multiline inline-level element (such as a multiline <span> element, by default) has a border box around each line.
This is an experimental technology
getClientRects()
Parameters:none
range = document.createRange(); range.selectNode(document.getElementsByTagName("div").item(0)); rectList = range.getClientRects();
example
Both the span and the paragraph have a border set. The client rects are in red. Note that the p has only one border box, while the span has multipleborder boxes.
Paragraph that spans multiple lines
Paragraph that spans multiple lines
Paragraph that spans multiple lines
Note that the border box doesn't include the number, so neither do the client rects.
Although the table's border box doesn't include the caption, the client rects do include the caption.
thead |
---|
tbody |
thead |
---|
tbody |
<div> <h3>A paragraph with a span inside</h3> <p>Both the span and the paragraph have a border set. The client rects are in red. Note that the p has only one border box, while the span has multipleborder boxes. </p> <div class="rect-1"> <strong>Original</strong> <p> <span>Paragraph that spans multiple lines</span> </p> </div> <div> <strong>p's rect</strong> <p class="withClientRectsOverlay"> <span>Paragraph that spans multiple lines</span> </p> </div> <div> <strong>span's rect</strong> <p> <span class="withClientRectsOverlay" >Paragraph that spans multiple lines</span > </p> </div> <h3>A list</h3> <p> Note that the border box doesn't include the number, so neither do the client rects. </p> <div class="rect-1"> <strong>Original</strong> <ol> <li>Item 1</li> <li>Item 2</li> </ol> </div> <div class="rect-1"> <strong>ol's rect</strong> <ol class="withClientRectsOverlay"> <li>Item 1</li> <li>Item 2</li> </ol> </div> <div class="rect-1"> <strong>each li's rect</strong> <ol> <li class="withClientRectsOverlay">Item 1</li> <li class="withClientRectsOverlay">Item 2</li> </ol> </div> <h3>A table with a caption</h3> <p>Although the table's border box doesn't include the caption, the client rects do include the caption. </p> <div class="rect-1"> <strong>Original</strong> <table> <caption> caption </caption> <thead> <tr> <th>thead</th> </tr> </thead> <tbody> <tr> <td>tbody</td> </tr> </tbody> </table> </div> <div class="rect-1"> <strong>table's rect</strong> <table class="withClientRectsOverlay"> <caption> caption </caption> <thead> <tr> <th>thead</th> </tr> </thead> <tbody> <tr> <td>tbody</td> </tr> </tbody> </table> </div> </div> <style> strong { text-align: center;} div .rect-1 { display: inline-block; width: 15vw;} div.rect-1 p, ol, table {border: 0.1vw solid blue;} span, li, th, td {border: 0.1vw solid green;} </style> <script> function addClientRectsOverlay(elt) { /* Absolutely position a div over each client rect so that its border width is the same as the rectangle's width. Note: the overlays will be out of place if the user resizes or zooms. */ const rects = elt.getClientRects(); for (const rect of rects) { const tableRectDiv = document.createElement("div"); tableRectDiv.style.position = "absolute"; tableRectDiv.style.border = "1px solid red"; const scrollTop = document.documentElement.scrollTop || document.body.scrollTop; const scrollLeft = document.documentElement.scrollLeft || document.body.scrollLeft; tableRectDiv.style.margin = tableRectDiv.style.padding = "0"; tableRectDiv.style.top = `${rect.top + scrollTop}px`; tableRectDiv.style.left = `${rect.left + scrollLeft}px`; // We want rect.width to be the border width, so content width is 2px less. tableRectDiv.style.width = `${rect.width - 2}px`; tableRectDiv.style.height = `${rect.height - 2}px`; document.body.appendChild(tableRectDiv); } } (() => { /* Call function addClientRectsOverlay(elt) for all elements with assigned class "withClientRectsOverlay" */ const elts = document.getElementsByClassName("withClientRectsOverlay"); for (const elt of elts) { addClientRectsOverlay(elt); } })(); </script>