---
title: 'The Box Model'
source: 'https://academia.sh/en/courses/css-fundamentals/box-model'
course: 'Visual Presentation with CSS'
language: en
updated: '2026-08-17T18:09:14+00:00'
license: 'CC BY-SA 4.0'
---

# The Box Model

Every element turning into a box made of four nested rectangles; the boundaries and arithmetic of the content, padding, border, and margin regions.

The previous topic resolved which declarations an element receives. The value is now settled:
a cell's `padding` value is `8px 12px`. But what that value means was never said. Where on
the cell do the 8 pixels get added? Does the added space grow the cell's total width, or does
it shrink the area of the text inside it?

The answer to these questions is the **box model**. The model is summed up in one sentence:
every element in the document tree turns into one or more rectangular boxes during layout, and
each box is made of four nested regions. This lesson defines those four regions and the
arithmetic between them.

## Four Regions

From outside in:

**The margin box** is the outermost rectangle. It carries the distance between the box and its
neighbors. It is transparent; no background is painted here.

**The border box** sits inside the margin. The border itself is drawn on this region's
boundary.

**The padding box** sits inside the border. It carries the distance between the content and
the border. Unlike the margin, **the background extends this far**.

**The content box** is the innermost rectangle. Text, an image, or child boxes sit here.

Three boundaries separate the regions, and each has its own name: the content edge, the
padding edge, the border edge, the margin edge. These names appear in the values of
properties like `background-clip`, `background-origin`, and `box-sizing`.

## Arithmetic

Each region's size is found by adding two edges to the region inside it. On the horizontal
axis:

$$\text{padding width} = \text{content width} + p_{\text{left}} + p_{\text{right}}$$
$$\text{border width} = \text{padding width} + b_{\text{left}} + b_{\text{right}}$$
$$\text{margin width} = \text{border width} + m_{\text{left}} + m_{\text{right}}$$

On the vertical axis the same sums are made with the top and bottom edges. The program below
runs these sums for two boxes: a cell in the measurement table and the page's masthead.

```js
// box-measure.mjs — computes the bounds of a box's four regions
function measureBox({ contentW, contentH, padding, border, margin }) {
  const [pt, pr, pb, pl] = padding;   // top, right, bottom, left
  const [bt, br, bb, bl] = border;
  const [mt, mr, mb, ml] = margin;
  const paddingBoxW = contentW + pl + pr;
  const paddingBoxH = contentH + pt + pb;
  const borderBoxW = paddingBoxW + bl + br;
  const borderBoxH = paddingBoxH + bt + bb;
  const marginBoxW = borderBoxW + ml + mr;
  const marginBoxH = borderBoxH + mt + mb;
  return { paddingBoxW, paddingBoxH, borderBoxW, borderBoxH, marginBoxW, marginBoxH };
}

const cell = {
  contentW: 120, contentH: 24,
  padding: [8, 12, 8, 12],
  border:  [0, 0, 1, 0],
  margin:  [0, 0, 0, 0],
};
const masthead = {
  contentW: 640, contentH: 96,
  padding: [24, 32, 24, 32],
  border:  [0, 0, 4, 0],
  margin:  [0, 16, 32, 16],
};

for (const [name, box] of [["cell", cell], ["masthead", masthead]]) {
  const r = measureBox(box);
  console.log(`--- ${name} ---`);
  console.log(`content     : ${box.contentW} x ${box.contentH}`);
  console.log(`padding box : ${r.paddingBoxW} x ${r.paddingBoxH}`);
  console.log(`border box  : ${r.borderBoxW} x ${r.borderBoxH}`);
  console.log(`margin box  : ${r.marginBoxW} x ${r.marginBoxH}`);
  console.log(`painted area (border box)  : ${r.borderBoxW * r.borderBoxH} px2`);
  console.log(`space occupied (margin box): ${r.marginBoxW * r.marginBoxH} px2`);
}
```

```
--- cell ---
content     : 120 x 24
padding box : 144 x 40
border box  : 144 x 41
margin box  : 144 x 41
painted area (border box)  : 5904 px2
space occupied (margin box): 5904 px2
--- masthead ---
content     : 640 x 96
padding box : 704 x 144
border box  : 704 x 148
margin box  : 736 x 180
painted area (border box)  : 104192 px2
space occupied (margin box): 132480 px2
```

The cell shows two observations. The `padding: 8px 12px` declaration, once expanded into four
values, added $12 + 12 = 24$ pixels horizontally and $8 + 8 = 16$ pixels vertically: content
width went from 120 to 144, height from 24 to 40. **Padding does not shrink the text's area;
it grows the box.** This is the answer to the question the previous topic asked.

Since only a bottom border was given, the width did not change and the height grew by 1
pixel. Because the margin is zero, the border box and the margin box are the same.

The masthead shows the effect of the margin: the border box is 704 units wide while the
margin box is 736. The 32 units in between are not painted, but they hold neighboring boxes at
a distance. The difference between the two area calculations — 132480 and 104192 — gives this
as a number.

## Which Property Applies to Which Region

The box model's practical value is knowing how far each visual property extends.

| Property | Region it covers |
|---|---|
| `background-color` | Content + padding + border (up to the border box) |
| `background-image` | Placed in the padding box by default, painted up to the border box |
| `border` | On the boundary of the border box |
| `box-shadow` | Outside the border box (or inside it with `inset`) |
| `outline` | Outside the border box, without taking up space |

Two rows deserve extra emphasis.

**The background covers the padding.** When a button gets a background color and padding, the
colored area is larger than the text — the padding has been painted. If the same space had
been given as margin instead, the colored area would be only as large as the text. This is why
the two declarations have different visual results.

**An outline takes up no space.** `outline` is drawn outside the border box but does not
affect layout; neighboring boxes sit as if nothing were there. This is why the focus indicator
is given with `outline`: the page does not shift when focus changes. If the same job were done
with `border`, the box would grow on every focused element and everything around it would
shift.

## Logical Edges

There are two ways to name edges. Physical names are based on the screen: `margin-top`,
`padding-left`, `border-right`. Logical names are based on writing direction:
`margin-block-start`, `padding-inline-start`, `border-inline-end`.

Logical names define two axes. The **inline axis** is the direction text flows in; in a
document written left to right, that is left to right. The **block axis** is the direction
lines stack in; in the same document, top to bottom.

In a document written right to left, `padding-inline-start` lands on the right edge, while
`padding-left` still stays on the left edge. Logical names are preferred so that the style
does not need to be rewritten when the document's language changes. Logical names are used
throughout this course; the information the `lang` attribute carries, from the Web
Fundamentals and HTML course, finds its counterpart here.

Shorthands for all four edges also exist in logical form: `margin-block` sets both block
edges at once, `margin-inline` sets both inline edges. The `margin-inline: auto` notation is
the standard way to center a block horizontally.

## The Station Page's Dimensions

```css
/* station.css — step 8: box dimensions */
.masthead {
  padding-block: 24px;
  padding-inline: 32px;
  margin-inline: 16px;
  margin-block-end: 32px;
  border-block-end: 4px solid #143a52;
  background-color: #f5f7f8;
}

.measurement-table th,
.measurement-table td {
  padding-block: 8px;
  padding-inline: 12px;
  border-block-end: 1px solid #d5dbe0;
}
```

The masthead's background color covers the padding; a gap of 24 and 32 units remains between
the heading and the edge of the colored area. The margin, on the other hand, sits outside the
colored area and keeps the masthead away from the edges.

In the cells, padding is 12 units horizontally, 8 vertically. What makes the table readable is
not the text itself but this gap between cells: once the padding is removed, columns stick
together and the bottom border alone is not enough to tell columns apart.

## Summary

- Every element turns into a box during layout; the box is made, from outside in, of the
  margin, border, padding, and content regions.
- Each region's size is found by adding two edges to the one inside it; padding does not
  shrink the content, it grows the box.
- The background extends up to the border box and covers the padding; the margin is
  transparent and only keeps neighbors at a distance.
- `outline` is drawn outside the border box but takes up no space; the focus indicator is
  given with it for this reason — with `border` instead, layout would shift as focus changed.
- Logical edge names resolve according to writing direction; the block axis is the direction
  lines stack in, the inline axis is the direction text flows in.

## Next Step

This lesson never gave the box a `width`; the content width was given, and the outer
dimensions were computed from it. But writing styles is usually done the other way around: a
width is declared, and the content size is derived from it. There are two separate models for
this derivation, and the difference between them changes a box's total width. The next lesson
compares the two models using the same numbers.
