Does getBoundingClientRect().width and height includes paddings and borders of element?

By default it returns width+padding+border Why?.

Because it's relative to the box-sizing CSS property, Which can have two values:

  1. content-box (default value)
  2. border-box

content-box: includes only the content. Border, padding and margin are not included.

This means when you set a width, That width is set to the content only then you add the padding and border.

console.log(document.querySelector('p').getBoundingClientRect().width)
p {
  box-sizing: content-box;
  width: 300px;
  padding: 10px;
  border: 2px solid;
}
<p>The console should log 324px because the width is 300px<br> padding is 10px left 10px right <br> border is 2px left 2px right<br> sums up to 300+10+10+2+2 = 324</p>


border-box: includes content, padding and border. margin is not included.

This means padding and border will be calculated within the defined width.

console.log(document.querySelector('p').getBoundingClientRect().width)
p {
  box-sizing: border-box;
  width: 300px;
  padding: 10px;
  border: 2px solid;
}
<p>console should log 300px Because padding's width and border's width have been calculated wihtin the specified width in the CSS</p>

Note: Height is not affected, But the same rules are applied to it too.


TLDR;

It will always return dimensions of the border box (green box bellow), which contains the content area, padding area and border area, as defined in the CSS Box Model.

CSS Box Model

The width style

However, one must not conflate content width (a property of the element layout) and style width (a constraint on the element layout, width: xxx; rules) which are very distinct things. The box-sizing will only affect whether the style width constraint should include the border and padding, or not.

Demonstration by example

In this first snippet, we are using box-sizing: border-box rule so that style width == boder + padding + content width. The result of getBoundingClientRect().width is 140, and it equals style width.

var x = document.getElementById("x");
console.log('getBoundingClientRect().width =', x.getBoundingClientRect().width);
console.log('getComputedStyle(x).width =', getComputedStyle(x).width);
#x {
  border: 20px solid blue;
  padding: 10px;
  width: 140px;
  box-sizing: border-box;
}
<div id=x>Border Box</div>

In the second snippet, we are using box-sizing: content-box rule so that style width == content width. The result of getBoundingClientRect().width is still 140 because the sum of border + padding + content width has not changed, only style width has changed.

var y = document.getElementById("y");
console.log('y.getBoundingClientRect().width =', y.getBoundingClientRect().width);
console.log('getComputedStyle(y).width =', getComputedStyle(y).width);
#y {
  border: 20px solid blue;
  padding: 10px;
  width: 80px;
  box-sizing: content-box;
}
<div id=y>Content Box</div>

References

  • MDN | Introduction to the CSS box model
  • CSSWG | CSS2 (Box Model)
  • MDN | Element.getBoundingClientRect()

Tags:

Javascript