CSS: Learning box model with analogies
Tags: css, learning, beginners, frontend
Published: 2024-07-08 21:29:31

## Introduction
If you're studying CSS, you may have already encountered the term _box model_. If not, don't worry; we'll address this topic in this article.

Every element in a web page is a rectangle called _box_; that's where the _box model_ name came from. Understanding how this model works is the basis for creating more complex layouts with CSS or aligning the items correctly.

![Peter Griffin CSS Meme GIF](https://i.giphy.com/media/v1.Y2lkPTc5MGI3NjExZXdoa2wwOXAyNHcwa2F5MmI4dHcxa3AwYnRpc2pyaTJsMzR3cjFydiZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/13FrpeVH09Zrb2/giphy.gif)

When inspecting an element (clicking with the right button or opening the **DevTools** with `Ctrl+Shift+C` or `F12`, depending on your browser) at the _Computed_ tab, you'll probably see something like this:

<figure>
  <a id="computed"></a>
  ![DevTools' Computed tab print](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kf8uwcl1pijc24a2s5qv.png)
  <figcaption>Fig.1 - Element's proprieties (_Computed_ tab)</figcaption>
</figure>

In the next section, we'll see what each part of this image means in detail.

## The **Box model**'s basic structure
Inspired by this article [[1]][Ref1], we will use the construction of a house on a lot as our example to illustrate the basic structure of the box model.

The parts that make up the structure are:

### Content
Content refers to the most central part of [Fig.1][Fig1] in blue and is related to the content within an HTML tag, such as text in a paragraph (**`<p>`**).

The content is composed of two properties, width and height.

In our example, the content will be the little house below ([Fig.2][Fig2]) (if you inspect the image of the house, you will see that the measurements are the same as [Fig.1][Fig1]). The dimensions of the house are 81px wide and 93px tall.

<figure>
 <a id="home"></a>
 ![House made in pixel art](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/04qnyrtcsnvy9dhtxpr3.png)
 <figcaption>Fig. 2 - Content (house) and its dimensions</figcaption>
</figure>

The content needs to be inside an HTML structure, so we will place our little house inside a lot to represent this structure:

<figure>
 <a id="casa-lote"></a>
 ![House positioned in the center of the lot](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s35or8xhu0dgqlf96hql.png)
 <figcaption>Fig. 3 - House positioned in the center of the lot</figcaption>
</figure>

### Padding
The green part of [Fig.1][Fig1] is the `padding` property, which creates space around the content.

The `padding` is demonstrated by the land part, where the garden will be, for example:

<figure>
 <a id="padding"></a>
 ![Padding added to the lot as an area of ​​land around the house](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n9mqclmz37kqdgbi7wq3.png)
 <figcaption>Fig. 4 - Padding added as a land area around the house</figcaption>
</figure>

### Border
Next, we have the `border` property, which is responsible for delimiting our content and is represented by yellow in [Fig.1][Fig1]. The border is the last property of our element that can be seen.

The border can be represented as the wall or, in our case, the fence of the house:

<figure>
 <a id="border"></a>
 ![Border added around the padding](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9jz6dnyxrche2h91ublv.png)
 <figcaption>Fig. 5 - Border added around the padding</figcaption>
</figure>

### Margin
Finally, we have the `margin` property in orange ([Fig.1][Fig1]), which includes an empty area around our element. As can be seen in the image:

<figure>
 <a id="margin"></a>
 ![Margin added to the element, creating an empty area around the border](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bb2tbrnugafdsga9thn5.png)
 <figcaption>Fig. 6 - Margin added to the element, creating an empty area around the border</figcaption>
</figure>

In this case, we reduced the `padding` so that the margin could be represented in the image.

## The `box-sizing` property

Now that we know the structure of the _box model_, we can address the `box-sizing` property. This property allows us to tell the browser how it should calculate the height and width of the element. We only have 2 possible values:

### content-box
This is the default value, where the element's height and width include only the content. Therefore, if we have content with a `height` and `width` of 100px, plus 10px of `padding`, 5px of `border` and 5 of `margin`, we will see that the size of our element changed from 100px to 130px:

<figure>
 <a id="content-box-example"></a>
 ![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tsf578lm7q1mnhmeqb4e.png)
 <figcaption>Fig. 7 - Div with 100 px height and width, 10px padding, 5px border and 5px margin using the default value `content-box`</figcaption>
</figure>

See the code here:
{% codepen https://codepen.io/fhmurakami/pen/QWXLdpX %}

This occurs because the _`height`_ and _`width`_ properties are only applied to the content (the blue part of [Fig.1][Fig1], remember?). However, we also added `padding`, `border` and `margin`:

100px (`height`/`width`) + 2 * 10px (`padding`) + 2 * 5px (`border`) + 2 * 5px (`margin`) = **140px**

> #### **Attention!** :warning:
> Huh?! :thinking:
>
> The image shows the element with 130px and not 140px!
> Exactly! Remember that `margin` is an external property of the element (or empty space around it) and should not be added to its height and width.

We can think that the `box-sizing` property, with the value `content-box,` will grow our element as we add more "layers."
To explain, I will use another analogy: Imagine a balloon, like those at a children's party, with sweets inside (it's like the Brazilian version of piñata).

<center>
   <table>
    <tr>
      <td>
        <figure>
          <a id="balloon"></a>
          <img alt="Balloon where we will put the sweets" src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jx739awww0jowwoonp8o.png" />
          <figcaption>Fig. 8 - Birthday party big balloon (<code>border</code>)</figcaption>
        </figure>
      </td>
      <td>
        <figure>
          <a id="candies"></a>
          <img alt="Sweets" src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qf5zf5o7tvhr0l0ez9jd.png" />
          <figcaption>Fig. 9 - Sweets (<code>content</code>)</figcaption>
        </figure>
      </td>
    </tr>
    <tr>
      <td colspan="2">
        <figure>
          <a id="balloon-candies"></a>
          <img alt="Balloon cut to display the candy inside" src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/23d4459r9hpc24dinodj.png" />
          <figcaption>Fig. 10 - Balloon with sweets inside</figcaption>
        </figure>
      </td>
    </tr>
  </table>
</center>

The sweets will be our content, with a fixed height and width. To make it possible to pop the balloon, we will add padding (air) inside the balloon. The balloon itself is the `border` and the `margin` is all the space around the balloon:

<figure>
 <a id="full-balloon"></a>
 <img alt="Balloon suspended from the ceiling with empty space around it" src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/huhrywjs718o6twheanr.png" />
 <figcaption>Fig. 11 - Sweets (<code>content</code>), air (<code>padding</code>), balloon (<code>border</code>), space around the balloon (<code>margin</ code> code>)</figcaption>
</figure>

Did you see how our element grew as we added more properties or if we added more air (`padding`) to the balloon?

Another example of a `content-box` using an analogy is a bag of popcorn in the microwave, where we initially have the `content` (corn), the `border` (paper bag), and the `margin` (internal space of the microwave). However, padding (air/steam inside the bag) is slowly added when heating.

### border-box
The other possible value for the `box-sizing` property is `border-box`. It is handy when you want to be sure of the space your element will occupy on the page; instead of limiting the height and width to just the content, it uses the entire element (`content + padding + border`). This helps create responsive layouts, as we guarantee that the elements have the exact size defined even using relative measurements (`%`, `em`, `rem` etc.).

Using the same example as [Fig.7][Fig7], but adding the `box-sizing: border-box;` property, we will have a final element with 100px height and width as previously defined.

<figure>
 <a id="border-box-example"></a>
 <img alt="Div with 100 px height and width, 10px padding, 5px border and 5px margin, but this time using the border-box value" src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ga0e6zyju1aqknvc71vy.png"/>
 <figcaption> Fig. 12 - Div with 100 px height and width, 10px padding, 5px border and 5px margin, but this time using the value <code>border-box</code> </figcaption>
</figure>

The difference is that our content has now been reduced to 70px in height and width so that it does not exceed 100px.

<figure>
 <a id="computed-border-box"></a>
 <img alt="Image of the computed tab showing that the content has been reduced to 70px in height and width" src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gn7pkcr45w7nup242uoi.png" / >
 <figcaption> Fig. 13 - <code>Computed</code> tab when inspecting the element</figcaption>
</figure>

See the code here:
{% codepen https://codepen.io/fhmurakami/pen/wvLwggR %}

In this case, we must think of something in which the final measurements cannot exceed a certain size. For this, we will use a cooler as the maximum size; therefore, the box will represent the `border` of our element:

<figure>
 <a id="empty-cooler"></a>
 ![Red thermal box with white border and no lid](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m9whp64mx7skktnnryns.png)
 <figcaption>
 Fig. 14 - Cooler (`border`)
 </figcaption>
</figure>

The `content` will be a drink that we want to chill, and the ice is the `padding`:

<center>
 <table>
 <tr>
 <td>
 <figure>
 <a id="barril-beer"></a>
 <img alt="Beer barrel" src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rq41pe25twoxpbzli7g2.png" />
 <figcaption>Fig. 15 - Beer barrel (<code>content</code>)</figcaption>
 </figure>
 </td>
 <td>
 <figure>
 <a id="ice"></a>
 <img alt="Ice cubes" src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3soshxk0pfw00i2iju2a.png" />
 <figcaption>Fig. 16 - Ice cubes (<code>padding</code>)</figcaption>
 </figure>
 </td>
 </tr>
 <tr>
 <td colspan="2">
 <figure>
 <a id="cooler-full"></a>
 <img alt="Cooler box with drink and ice" src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7rpvts1fh4n098sntuw7.png" />
 <figcaption>Fig. 17 - Cooler with the drink and ice</figcaption>
 </figure>
 </td>
 </tr>
 </table>
</center>

Note that the more ice we add, the smaller the drink we can chill. As we cannot have content with negative measurements, the smallest possible size will be 0px. However, assuming that our box is 100px `height` by 120px `width`, and we define a `padding` of 60px, we will have all 120px of ice both horizontally and vertically; that is, the ice will overflow to the cooler.

<figure>
 <a id="padding-overflow"></a>
 ![Red thermal box with ice exceeding the maximum height of the box](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7v4qnxgw0piducwagqdl.png)
 <figcaption>
   18 - Ice overflowing at the maximum limit (height) of the cooler
 </figcaption>
</figure>

The same happens with our HTML element:

<figure>
 <a id="border-box-overflow"></a>
 ![Image of the computed tab showing that the content has been reduced to 0px in height and width, but the total height of the element has increased to 150px](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5uzc82a908v1a80mhoe3.png)
 <figcaption>
 Fig. 19 - Inspecting the element, we can see that when adding padding greater than the total size of the element, the content was reduced to 0x0 px, and the height increased to 150px, even with `box-sizing: border-box `
 </figcaption>
</figure>

See the code here:
{% codepen https://codepen.io/fhmurakami/pen/mdZbJZp %}

## Conclusion
Now that you know the basic structure of the _Box Model_ and the `box-sizing` property, it will be easier to understand how the elements behave on your web page and know when to use each value ​​(`content-box` and ` border-box`). Inspecting the elements of the websites you use daily, you will see that the majority use `border-box` for their elements, as this property has made responsive design much easier. :)

Congratulations on getting this far!

![Beer mugs toasting](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lsjnxtd5bpk1hyen7iqq.png)

Do you have any questions or suggestions? Feel free to leave a comment or, if you prefer, send a private message on [LinkedIn](https://www.linkedin.com/in/felipe-murakami/).

> ### **Note** ❗🚫
> I made all images in this article; please do not use them without due consent/credit.
> The free ready-made assets I used are in the references, and use for non-commercial projects is permitted.

## References
<a id="ref1"></a>[1] [The CSS Box Model Explained by Living in a Boring Suburban Neighborhood](https://blog.codeanalogies.com/2017/03/27/the-css-box-model-explained-by-living-in-a-boring-suburban-neighborhood/)
<a id="ref2"></a>[2] [MDN Web Docs - The box model](https://developer.mozilla.org/en-US/docs/Learn/CSS/Building_blocks/The_box_model)
<a id="ref3"></a>[3] [MDN Web Docs - Introduction to the CSS basic box model](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_box_model/Introduction_to_the_CSS_box_model)
<a id="ref4"></a>[4] [MDN Web Docs - box-sizing](https://developer.mozilla.org/en-US/docs/Web/CSS/box-sizing)
<a id="ref5"></a>[5] [W3Schools - CSS Box Model](https://www.w3schools.com/css/css_boxmodel.asp)
<a id="ref6"></a>[6] [W3Schools - CSS Box Sizing](https://www.w3schools.com/css/css3_box-sizing.asp)
<a id="ref7"></a>[7] [The Odin Project - Foundations Course - The Box Model](https://www.theodinproject.com/lessons/foundations-the-box-model#introduction)
<a id="ref8"></a>[8] [Learn CSS BOX MODEL - With Real World Examples](https://www.youtube.com/watch?v=nSst4-WbEZk)
<a id="ref9"></a>[9] [Learn CSS Box Model in 8 minutes](https://www.youtube.com/watch?v=rIO5326FgPEhttps://www.youtube.com/watch?v=rIO5326FgPE)
<a id="ref10"></a>[10] [box-sizing: border-box (EASY!)](https://www.youtube.com/watch?v=HdZHcFWcAd8)
<a id="ref11"></a>[11] [Assets used in the images for the Box Model examples](https://butterymilk.itch.io/tiny-wonder-farm-asset-pack)
<a id="ref12"></a>[12] [Assets - Beer mug](https://henrysoftware.itch.io/godot-pixel-food)

[Fig1]: #computed
[Fig2]: #casa
[Fig3]: #casa-lote
[Fig4]: #padding
[Fig5]: #border
[Fig6]: #margin
[Fig7]: #content-box-example
[Fig8]: #baloon
[Fig9]: #candies
[Fig10]: #baloon-candies
[Fig11]: #baloon-full
[Fig12]: #border-box-example
[Fig13]: #computed-border-box
[Fig14]: #cooler-vazio
[Fig15]: #barril-chopp
[Fig16]: #border-box-overflow
[Fig17]: #cooler-cheio
[Fig18]: #padding-overflow
[Fig19]: #border-box-overflow

[Ref1]: #ref1