I am unable to find an explicit reference for the use of these functions:
getBBox()
vs getBoundingClientRect()
vs getClientRects()
.
This is an example I copied from MDN Element.getClientRects() and I added addBoundingClientRectOverlay
function to compare addClientRectsOverlay
.
You can see the red rectangle is from getClientRects
and the black dash rectangle is from getBoundingClientRect
, so you can tell what's different.
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.
var rects = elt.getClientRects();
for (var i = 0; i != rects.length; i++) {
var rect = rects[i];
var tableRectDiv = document.createElement("div");
tableRectDiv.style.position = "absolute";
tableRectDiv.style.border = "1px solid red";
var scrollTop =
document.documentElement.scrollTop || document.body.scrollTop;
var 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);
}
}
function addBoundingClientRectOverlay(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.
var rect = elt.getBoundingClientRect();
var tableRectDiv = document.createElement("div");
tableRectDiv.style.position = "absolute";
tableRectDiv.style.border = "1px dashed #321";
var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
var scrollLeft =
document.documentElement.scrollLeft || document.body.scrollLeft;
tableRectDiv.style.margin = tableRectDiv.style.padding = "0";
tableRectDiv.style.top = rect.top + scrollTop+1 + "px";
tableRectDiv.style.left = rect.left + scrollLeft+1 + "px"; // we want rect.width to be the border width, so content width is 2px less.
tableRectDiv.style.width = rect.width - 4 + "px";
tableRectDiv.style.height = rect.height - 4 + "px";
document.body.appendChild(tableRectDiv);
}
(function() {
/* call function addClientRectsOverlay(elt) for all elements with assigned css class "withClientRectsOverlay" */
var elt = document.getElementsByClassName("withClientRectsOverlay");
for (var i = 0; i < elt.length; i++) {
addClientRectsOverlay(elt[i]);
addBoundingClientRectOverlay(elt[i]);
}
})();
strong {
text-align: center;
}
div {
display: inline-block;
width: 150px;
}
div p,
ol,
table {
border: 1px solid blue;
}
span,
li,
th,
td {
border: 1px solid green;
}
A paragraph with a span inside
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 multiple border boxes.
Original
Paragraph that spans multiple lines
p's rect
Paragraph that spans multiple lines
span's rect
Paragraph that spans multiple lines
A list
Note that the border box doesn't include the number, so neither do the client rects.
Original
- Item 1
- Item 2
ol's rect
- Item 1
- Item 2
each li's rect
- Item 1
- Item 2
A table with a caption
Although the table's border box doesn't include the caption, the client rects do include the caption.
Original
caption
thead
tbody
table's rect
caption
thead
tbody