Boxes and positioning

The box model

Visualize every element as content surrounded by padding, border, and margin, and see how those layers determine occupied space.

Every element on the page is a rectangle. The browser turns each one into a box and lays the boxes out. What’s inside that box is the box model, and it’s the base of everything in layout.

From the inside out, a box has four layers:

  1. content: the text or image itself
  2. padding: space between the content and the border
  3. border: the line around the padding
  4. margin: space outside the border, between this box and its neighbors

Let’s put numbers on it:

.card {
  width: 20rem;
  padding: 1rem;
  border: 2px solid;
  margin: 1rem;
}

How wide is this card on screen? You might say 20rem. By default, it isn’t.

width applies to the content area only. Then the browser adds the padding on both sides, then the border on both sides. With a 16px root font size that’s 320 + 16 + 16 + 2 + 2, so the visible border-to-border width is 356px. The margin sits outside that, another 16px on each side, pushing other boxes away.

This default behavior is called content-box, and we’ll change it in the next lesson. For now, remember that padding and border add to the declared width.

Background and margin

The background paints the content and the padding, and goes under the border too. It never paints the margin. That’s how you tell them apart when a gap looks wrong: if the space has the element’s background color, it’s padding. If it doesn’t, it’s margin.

Height is less obedient than width

Don’t assume height works the same way. If you set a height smaller than the wrapped text, the text overflows the box. Elements also refuse to shrink below their longest unbreakable word. I rarely set height on anything that contains text. I let the content decide, and set min-height when I need a floor.

The diagram in DevTools

Select the card in DevTools and find the box-model diagram in the Layout section. It’s a set of nested rectangles with the computed size of each layer: content, padding, border, margin. Hover a layer and it highlights on the page.

This diagram is the fastest way to answer “why is this box bigger than I asked for?”. I look at it before I touch a single value.

Try this on the course page. Apply the rule above to .card. Our stylesheet already sets box-sizing: border-box on everything, so uncheck that declaration in DevTools first to see the default behavior. Change padding, then border, then margin, one at a time. Before each change, predict the border-box width in the diagram. Then paste a very long word with no spaces into a card and watch the content push past your numbers. That’s the content constraint winning over the declaration.

Lesson completed