The box model
The browser rendering engine takes every single HTML element to be bounded by a box. In other words, rendering content on the web is based on a box model.
The box encapsulates all the content, padding and borders of a given element. It is a grouped unit which browsers use to layout content on a webpage, wrap text, set scrollbars and much more. It is also utilised in calculating an element's offsets, its width and height.
Let's see how this box looks for an HTML element.
The bounding box essentially comprises of the following three components:
- At its core lies the content box where all the actual content dwells
- The padding box holds the padding of the element, given by
padding
. - Finally the border box holds the borders of the element defined by
border
.
When the element has only padding and content in it, its padding box equals the bounding box; when it has only borders and content in it the border box equals the bounding box; when it has all three again its border box equals its bounding box; and when it has none of these its content box equals the bounding box.
A method to help
In JavaScript, we can use the getBoundingClientRect()
method on an element node to get the various dimensions of its bounding box i.e its width, height and so on. The method returns a DOMRect
object with a number of properties accounting for different aspects of the bounding box.
Suppose we have the following CSS for an element p
:
p {
width: 200px;
height: 100px;
padding: 50px;
border: 25px solid black;
}
What can you tell about the width of the bounding box of this element?
Determine the width of the bounding box of the p
element shown above.
- 200px
- 275px
- 300px
- 350px
From the code above we can deduce it should be 350px (200px for the width of the content box, 50 + 50 = 100px for the padding on both sides and, 25 + 25 = 50px for the borders on both sides).
Let's see what the method getBoundingClientRect()
gives us in its width
property:
// Suppose that ele = document.getElementsByTagName("p")[0];
ele.getBoundingClientRect().width; // 350
So as you can see it matches the width we calculated above i.e total width of the bounding box by summing the content box's width and the padding and border values.
Apart from the width, let's explore what else does this method offers us with for an element's dimensions.
ele.getBoundingClientRect(); // DOMRect {x: 0, y: 0, width: 350, height: 250, top: 0, left: 0, bottom: 0, right: 0}
The object it returns contains the properties:
x
: same asleft
y
: same astop
width
: width of the element's bounding boxheight
: height of the element's bounding boxleft
: distance of the left edge of the element from the left of the viewporttop
: distance of the top edge the element from the top of the viewportright
: distance of the element's right edge from the left of the viewportbottom
: distance of the bottom edge of the element from the top of the viewport
x
and y
, therefore it is best to stick with left
and top
respectively.ClientRect
object instead of DOMRect
, without the properties x
and y
.The properties width
and height
are clear in their meaning and you can infer right away what they would return, right?
What might be new for you are the rest of the properties also known as offsets of an element. Offsets are distances of an element's edges from the viewport, commonly used when scroll events are needed to be attached to a document. We'll see them in more detail in the next chapters but for now let's just take a simple look at the properties left
and top
.
First for top
:
A paragraph of 50px height.
var ele = document.getElementById("p1");
var rect = ele.getBoundingClientRect();
console.log(rect.top); // 124
Now for left
:
A paragraph with 50px left margin.
var ele = document.getElementById("p1");
var rect = ele.getBoundingClientRect();
console.log(rect.left); // 58
In both these cases we get values greater than the expected ones due to preset margins on HTML elements p
and body
. Try removing them using CSS and then again log the offset values above and you'll get 100 and 50 respectively. It's all about thinking and understanding!