🚀 New batches open: Advanced Excel • Power BI • SQL • AI for Analytics — Book a free demo

Day 8 — The box model

Every element is a rectangle with four layers. Almost every "why is this not lining up" question is answered here.

The four layers

content  →  padding  →  border  →  margin
  • padding - space inside the border. It takes the background colour.
  • border - the line itself.
  • margin - space outside the border, pushing other elements away. Always transparent.
<style>
  .demo {
    background: #E8EEF8;
    padding: 20px;
    border: 3px solid #1D3B73;
    margin: 24px;
  }
</style>

<p>Before</p>
<div class="demo">Content. The tinted area is the padding.</div>
<p>After</p>

Change the padding to 0 and the tint hugs the text. Change the margin and the gap to the paragraphs above and below moves - but the tint does not grow.

Shorthand

<style>
  .one   { padding: 10px;                 background:#EEF3FA; }
  .two   { padding: 10px 30px;            background:#E8EEF8; }
  .three { padding: 5px 20px 40px;        background:#EEF3FA; }
  .four  { padding: 5px 10px 20px 40px;   background:#E8EEF8; }
</style>

<p class="one">One value: all four sides</p>
<p class="two">Two: top-bottom, then left-right</p>
<p class="three">Three: top, left-right, bottom</p>
<p class="four">Four: top, right, bottom, left - clockwise</p>
Clockwise from the top Four values always go top, right, bottom, left. Some people remember it as TRouBLe. The same order works for margin, border-width and border-radius.

The width problem, and the one-line fix

By default, width: 300px means the content is 300px. Padding and border are then added on top, so the box on screen is wider than the number you wrote.

<style>
  .a, .b {
    width: 300px; padding: 20px; border: 5px solid #1D3B73;
    background: #E8EEF8; margin-bottom: 12px;
  }
  .b { box-sizing: border-box; }
</style>

<div class="a">Default: 300 + 20 + 20 + 5 + 5 = 350px on screen</div>
<div class="b">border-box: exactly 300px on screen</div>
Put this at the top of every stylesheet you write
*, *::before, *::after { box-sizing: border-box; }
Now width means the width you see, padding and border included. Two boxes at width: 50% actually sit side by side instead of overflowing. Practically every real site does this.

Margins collapse. Padding does not.

Two stacked elements with 30px margins do not end up 60px apart. They end up 30 apart - the larger margin wins and the smaller disappears.

<style>
  .m { margin: 30px 0; background: #E8EEF8; }
  .p { padding: 30px 0; background: #FDF3DA; }
</style>

<div class="m">Margin 30</div>
<div class="m">Margin 30 - the gap is 30, not 60</div>
<div class="p">Padding 30</div>
<div class="p">Padding 30 - this gap really is 60</div>

This surprises everybody once. It only happens vertically, and only with margins.

block, inline and inline-block

<style>
  span.a { background:#E8EEF8; width:200px; padding:10px; }
  span.b { background:#FDF3DA; width:200px; padding:10px;
           display:inline-block; }
  .c     { background:#EEF3FA; width:200px; padding:10px;
           display:block; }
</style>

<p>An <span class="a">inline span</span> ignores width.</p>
<p>An <span class="b">inline-block span</span> obeys it.</p>
<div class="c">A block takes its own line.</div>
displayBehaves like
blockOwn line, full width available. div, p, h1, section.
inlineFlows in the text. Ignores width, height and vertical margins. span, a, strong.
inline-blockFlows in the text but obeys width and height.
noneGone. Takes up no space at all.
flexTomorrow.

Centring a block

<style>
  .wrap {
    max-width: 420px;
    margin: 0 auto;
    padding: 16px;
    background: #E8EEF8;
    box-sizing: border-box;
  }
</style>

<div class="wrap">
  <p>max-width plus margin: 0 auto centres this and stops it
     stretching too wide on a big screen.</p>
</div>
max-width, not width width: 420px stays 420px even on a 360px phone, so the page scrolls sideways. max-width: 420px means "at most 420, less if there is less room". Use max-width for containers, nearly always.

A card, using everything so far

<style>
  *, *::before, *::after { box-sizing: border-box; }
  body { font-family: system-ui, sans-serif; background:#F6F8FC; }
  .card {
    max-width: 380px;
    background: #fff;
    border: 1px solid #D3DDEC;
    border-radius: 12px;
    padding: 20px;
    box-shadow: 0 4px 14px rgba(10,26,61,.08);
  }
  .card h3 { margin: 0 0 6px; color: #0A1A3D; }
  .card p  { margin: 0; color: #4A5A78; line-height: 1.6; }
</style>

<div class="card">
  <h3>Advanced Excel</h3>
  <p>Six weeks. Formulas, pivots and dashboards on real reports.</p>
</div>

Try these yourself

  1. Draw a box with 20px padding, a 2px border and 40px of margin, and describe what each does.
  2. Make two boxes 50% wide sit side by side. Then remove border-box and see what breaks.
  3. Prove margin collapsing to yourself with two stacked divs.
  4. Centre a 500px container on the page using max-width.
  5. Explain the difference between padding and margin in one sentence.