There is a good article on MDN that explains the theory behind those concepts:
https://developer.mozilla.org/en-US/docs/Web/API/CSS_Object_Model/Determining_the_dimensions_of_elements
It also explains the important conceptual differences between boundingClientRect's width/height vs offsetWidth/offsetHeight.
Then, to prove the theory right or wrong, you need some tests.
That's what I did here: https://github.com/lingtalfi/dimensions-cheatsheet
It's testing for chrome53, ff49, safari9, edge13 and ie11.
The results of the tests prove that the theory is generally right.
For the tests, I created 3 divs containing 10 lorem ipsum paragraphs each.
Some css was applied to them:
.div1{
width: 500px;
height: 300px;
padding: 10px;
border: 5px solid black;
overflow: auto;
}
.div2{
width: 500px;
height: 300px;
padding: 10px;
border: 5px solid black;
box-sizing: border-box;
overflow: auto;
}
.div3{
width: 500px;
height: 300px;
padding: 10px;
border: 5px solid black;
overflow: auto;
transform: scale(0.5);
}
And here are the results:
div1
offsetWidth: 530 (chrome53, ff49, safari9, edge13, ie11)
offsetHeight: 330 (chrome53, ff49, safari9, edge13, ie11)
bcr.width: 530 (chrome53, ff49, safari9, edge13, ie11)
bcr.height: 330 (chrome53, ff49, safari9, edge13, ie11)
clientWidth: 505 (chrome53, ff49, safari9)
clientWidth: 508 (edge13)
clientWidth: 503 (ie11)
clientHeight: 320 (chrome53, ff49, safari9, edge13, ie11)
scrollWidth: 505 (chrome53, safari9, ff49)
scrollWidth: 508 (edge13)
scrollWidth: 503 (ie11)
scrollHeight: 916 (chrome53, safari9)
scrollHeight: 954 (ff49)
scrollHeight: 922 (edge13, ie11)
div2
offsetWidth: 500 (chrome53, ff49, safari9, edge13, ie11)
offsetHeight: 300 (chrome53, ff49, safari9, edge13, ie11)
bcr.width: 500 (chrome53, ff49, safari9, edge13, ie11)
bcr.height: 300 (chrome53, ff49, safari9)
bcr.height: 299.9999694824219 (edge13, ie11)
clientWidth: 475 (chrome53, ff49, safari9)
clientWidth: 478 (edge13)
clientWidth: 473 (ie11)
clientHeight: 290 (chrome53, ff49, safari9, edge13, ie11)
scrollWidth: 475 (chrome53, safari9, ff49)
scrollWidth: 478 (edge13)
scrollWidth: 473 (ie11)
scrollHeight: 916 (chrome53, safari9)
scrollHeight: 954 (ff49)
scrollHeight: 922 (edge13, ie11)
div3
offsetWidth: 530 (chrome53, ff49, safari9, edge13, ie11)
offsetHeight: 330 (chrome53, ff49, safari9, edge13, ie11)
bcr.width: 265 (chrome53, ff49, safari9, edge13, ie11)
bcr.height: 165 (chrome53, ff49, safari9, edge13, ie11)
clientWidth: 505 (chrome53, ff49, safari9)
clientWidth: 508 (edge13)
clientWidth: 503 (ie11)
clientHeight: 320 (chrome53, ff49, safari9, edge13, ie11)
scrollWidth: 505 (chrome53, safari9, ff49)
scrollWidth: 508 (edge13)
scrollWidth: 503 (ie11)
scrollHeight: 916 (chrome53, safari9)
scrollHeight: 954 (ff49)
scrollHeight: 922 (edge13, ie11)
So, apart from the boundingClientRect's height value (299.9999694824219 instead of expected 300) in edge13 and ie11, the results confirm that the theory behind this works.
From there, here is my definition of those concepts:
- offsetWidth/offsetHeight: dimensions of the layout border box
- boundingClientRect: dimensions of the rendering border box
- clientWidth/clientHeight: dimensions of the visible part of the layout padding box (excluding scroll bars)
- scrollWidth/scrollHeight: dimensions of the layout padding box if it wasn't constrained by scroll bars
Note: the default vertical scroll bar's width is 12px in edge13, 15px in chrome53, ff49 and safari9, and 17px in ie11 (done by measurements in photoshop from screenshots, and proven right by the results of the tests).
However, in some cases, maybe your app is not using the default vertical scroll bar's width.
So, given the definitions of those concepts, the vertical scroll bar's width should be equal to (in pseudo code):
Note, if you don't understand layout vs rendering please read the mdn article.
Also, if you have another browser (or if you want to see the results of the tests for yourself), you can see my test page here: http://codepen.io/lingtalfi/pen/BLdBdL
element.getBoundingClientRect()
(see the note at developer.mozilla.org/en-US/docs/Web/API/Element.clientWidth) – Williford