Há um bom artigo sobre o MDN que explica a teoria por trás desses conceitos:
https://developer.mozilla.org/en-US/docs/Web/API/CSS_Object_Model/Determining_the_dimensions_of_elements
Ele também explica as importantes diferenças conceituais entre a largura / altura do boundingClientRect e o offsetWidth / offsetHeight.
Então, para provar a teoria certa ou errada, você precisa de alguns testes. Foi o que fiz aqui: https://github.com/lingtalfi/dimensions-cheatsheet
Está testando para chrome53, ff49, safari9, edge13 e ie11.
Os resultados dos testes provam que a teoria geralmente está correta. Para os testes, criei 3 divs contendo 10 parágrafos de lorem ipsum cada. Algum css foi aplicado a eles:
.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);
}
E aqui estão os resultados:
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)
- altura de bcr: 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)
Portanto, além do valor da altura do boundingClientRect (299.9999694824219 em vez do esperado 300) em edge13 e ie11, os resultados confirmam que a teoria por trás disso funciona.
A partir daí, aqui está minha definição desses conceitos:
- offsetWidth / offsetHeight: dimensões da caixa de borda do layout
- boundingClientRect: dimensões da caixa de borda de renderização
- clientWidth / clientHeight: dimensões da parte visível da caixa de preenchimento do layout (excluindo barras de rolagem)
- scrollWidth / scrollHeight: dimensões da caixa de preenchimento do layout, se não foi restringida pelas barras de rolagem
Nota: a largura da barra de rolagem vertical padrão é 12px em edge13, 15px em chrome53, ff49 e safari9 e 17px em ie11 (feita por medidas no photoshop a partir de capturas de tela e comprovada pelos resultados dos testes).
No entanto, em alguns casos, talvez seu aplicativo não esteja usando a largura da barra de rolagem vertical padrão.
Portanto, dadas as definições desses conceitos, a largura da barra de rolagem vertical deve ser igual a (no pseudo-código):
Observe que, se você não entender o layout versus a renderização, leia o artigo mdn.
Além disso, se você tiver outro navegador (ou se quiser ver os resultados dos testes por conta própria), poderá ver minha página de teste aqui: http://codepen.io/lingtalfi/pen/BLdBdL
element.getBoundingClientRect()
(veja a nota no developer.mozilla.org/en-US/docs/Web/API/Element.clientWidth )