Subscribe now

The Box Model [05.13.2016]

Today we are going to look at the box model in CSS. The box model is the system in which all elements are rendered: as boxes. Yes, even circles are just boxes with very round corners in CSS.

Value Ordering Shorthand

Before we get into the depths of the box model, let's take a moment to look at the different ways values can be ordered on structural elements. These are called Shorthand Properties and you'll see them used all over, because they are so convenient. There are other shorthand properties, but today we'll just look at the ones related to the box model.

The normal way you list a set of values for a property like margin is to pass all four values on different rules, like this:

.box {
  margin-top: 1px;
  margin-right: 2px;
  margin-bottom: 3px;
  margin-left: 4px;
}

The easiest short hand is to pass them all at the same time though:

.box {
  margin: 1px 2px 3px 4px;
}

The values are always ordered in the same direction: top, right, bottom, left. This is easy to remember because it follows an analog clock that starts on 12. In the example we have a 1px margin on the top, a 2px margin on the right, a 3px margin on the bottom and a 4px margin on left.

Another shorthand is to only pass two values. The first value is for both the top and bottom, while the second value is for the left and right sides. This two value shorthand is very popular.

.box {
  margin: 1px 2px;
}

The three value shorthand, is frankly confusing. I recommend against using it. The first value in the example puts a 1px margin on the top, a 2px margin on both the right and left sides, and a 3px margin on bottom. I think it's easier for later reading of your code to just spell out all four values over this.

.box {
  margin: 1px 2px 3px;
}

The last shorthand is really easy: one value and it's repeated on all four sides, like this.

.box {
  margin: 1px;
}

This shorthand is really useful to know, as you'll see it all over.

The Box Model

Moving on to the box model. Adding the word model makes it sound complicated, but the box model is simply how the browser renders the rectangular blocks of content. Luckily the model is consistent across all container types, so once your learn it once it works everywhere.

Working from the inside out, when you set a height or width on an element, it is set on the inside of that element. All of the padding, border, margin, and offset happens outside of the defined size. Let's go ahead a setup basic page, with a container called box, so we can see that model in action. We'll also set a width on that box.

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>The Box Model</title>
    <link rel="stylesheet" href="normalize.css" type="text/css">
    <link rel="stylesheet" href="typebase.css" type="text/css">
    <link rel="stylesheet" href="style.css" type="text/css">
  </head>
  <body>
    <header>
      <h1>The Box Model</h1>
    </header>
    <main>
      <div class="box">The Box In Question</div>
    </main>
  </body>
</html>
header {
  text-align: center;
}

main {
  background-color: lightgrey;
}

.box {
  background-color: green;
  width: 20em;
}

Now we can inspect the element with Chrome, and select Computed. We can see this great box model diagram in the developer tools. Lets add some padding and refresh, and see how the diagram changes.

.box {
  background-color: green;
  width: 20em;
  padding: 2em;
}

In the tools we see we now have 44px of padding around the content of the box. This 44px comes from being 2em. Since we are using Typebase, and have the font-size set to 137.5% on the html element, and the default font size is 16px, that gives us 16px * 137.5% = 22px -- a 22px em.

This is also why our width on box is showing as 440px in width. We set it to 20em, and 20em*22(px/em)=440px.

Next we'll add a border, which is applied to the outside of our padding:

.box {
  background-color: green;
  width: 20em;
  padding: 2em;
  border: 1em solid black;
}

And finally a margin, which is applied outside of the border.

.box {
  background-color: green;
  width: 20em;
  padding: 2em;
  border: 1em solid black;
  margin: 2em;
}

Now we'll calculate the effective width of this element.

   2 * 44px margin
   2 * 1px border
   2 * 44px padding
+  440px element width
-----------------------
530px total width / 22(px/em) = 24em (plus 2 pixels from the border), which matches our CSS!

You'll always want to keep in mind your available space when setting width on an element. You have to undersize the content area to give enough room for all of the additional parts of the box model, if you are using any.

Centering with margin: auto

One great trick is to use the margin rule to center a block. If we just add the keyword auto after our 2em, then we'll be telling the browser to put a 2em margin on top and bottom, but to automatically figure out the margin on the left and right.

.box {
  background-color: green;
  width: 20em;
  padding: 2em;
  border: 1em solid black;
  margin: 2em auto;
}

Note that you have to have a defined width for this to work. Otherwise the container element will take all the available horizontal space, and it wont be able to be centered.

.box {
  background-color: green;
  /*width: 20em;*/
  padding: 2em;
  border: 1em solid black;
  margin: 2em auto;
}

Summary

In summary, today we looked at several shorthand methods for passing values to container rules, dove into how a browser renders an element via the box model and looked at a centering strategy for margin: auto. A great exercise is to take a scrap of paper and draw out the box model from memory, labeling all the parts of it. Don't forget to show where height and width fit into the model!

Thats all for today, see you next time!

Resources