Brainlag
  1. Library
  2. Concepts
  3. Web

The box model

Every element is a box of content, padding, border and margin. box-sizing decides whether width means the content or the whole box.

Web10 min

Four layers per box

The browser draws every element as a rectangle with four layers, from the inside out:

  • content: the text or image itself
  • padding: space inside the border, coloured by the background
  • border: the line around it
  • margin: space outside the border, always see-through, pushing other boxes away
CSS
.card {
  padding: 16px;
  border: 2px solid #333;
  margin: 24px;
}

Padding makes a button feel roomier. Margin moves it away from its neighbours. Open your browser's dev tools, inspect any element and you will see these four layers drawn as nested boxes.

What width really measures

By default width: 200px sets only the content. Padding and border are added on top, so a 200px card with 20px padding and a 5px border is really 250px wide. That surprise breaks layouts all the time.

CSS
* {
  box-sizing: border-box;
}

With border-box, width means the whole box including padding and border, and the content shrinks to fit. Most sites put that rule at the top of their CSS.

Run it: two cards, same width

Run it, then change one thing and run it again.

index.html to run
<style>
  .card {
    width: 200px;
    padding: 20px;
    border: 5px solid #46a9b3;
    margin: 12px 0;
    background: #eef7f8;
  }
  .fixed {
    box-sizing: border-box;
  }
</style>
<div class="card">content-box: I am wider than 200px</div>
<div class="card fixed">border-box: I am exactly 200px</div>
<script>
  for (const card of document.querySelectorAll(".card")) {
    console.log(card.textContent.split(":")[0], "is", card.offsetWidth + "px wide");
  }
</script>

A card that spills over

The profile card should be exactly 300px wide on screen, so it fits the 300px column. It comes out 350px. Fix it with one CSS line, without changing the width, padding or border.

exercise_1.html to run
<style>
  .column { width: 300px; background: #ddd; }
  .profile {
    width: 300px;
    padding: 20px;
    border: 5px solid #222;
  }
</style>
<div class="column">
  <div class="profile">Zara, level 12</div>
</div>

Code editor. Press Control or Command plus Enter to run the code. Tab indents; to move focus out of the editor, press Escape and then Tab.