The Academy

Loading the search index…

Searches the academy on this device only.

The box model, Flexbox and Grid

Understand that every element is a box with content, padding, border and margin, then arrange boxes in a row or a grid with Flexbox and CSS Grid.

30 minelementary

Marking a lesson as read does not prove you can do it. Skills count as demonstrated when you pass the quiz (not yet) and complete the practical tasks (not yet).

By the end of this lesson you will be able to

  • Describe the four layers of the box model: content, padding, border and margin.
  • Change padding, border and margin on an element and predict the effect.
  • Place items in a row, centred or spaced out, using Flexbox.
  • Create a simple grid of equal columns with CSS Grid.
  • Choose Flexbox for one direction and Grid for rows and columns together.

Once colours and fonts are set, the next question is where things go on the page. CSS treats every element as a rectangular box, and learning how those boxes take space is the key to layout. After that, two modern tools, Flexbox and Grid, let you line boxes up in rows and columns without any tricks. Understanding these will also help you fix the most common web puzzle: why is there a gap here, and why does this box not fit?

Every element is a box

The Box model says that every element is a rectangle made of four layers, from the inside out. The content is the text or image itself. Padding is clear space between the content and its border. The border is a line around the padding. The margin is clear space outside the border that keeps other elements away. Think of a framed photograph on a wall: the photo is the content, the white mount is the padding, the frame is the border, and the gap to the next picture is the margin.

Diagram

The four layers of the box model, from outside to inside.

Outside

MarginSpace outside, always transparent
BorderThe line around the box
PaddingSpace inside, shows background colour
ContentThe text or image
The four layers of the box model, from outside to inside.
Read this figure as text

A stack of four nested layers: margin, border, padding and content.

Four layers, listed from outermost to innermost. Margin: empty space outside the border that pushes neighbours away. Border: the line around the box. Padding: empty space between the border and the content, inside the box and showing its background colour. Content: the text or image itself. Background colour fills the padding but never the margin.

CSS
.card {
  padding: 16px;
  border: 2px solid #1b5e20;
  margin: 24px;
  background-color: #eef7ee;
}
A box with all four layers set.

A value on its own such as padding: 16px; sets all four sides. You can give two values (top and bottom, then left and right) or four (top, right, bottom, left, clockwise like a clock). Border takes a width, a style and a colour. Margin accepts the same shorthand. The unit px is a pixel, a tiny square of the screen; rem scales with the reader's text size, which is kinder to people who enlarge text.

One surprise catches nearly everyone. By default, a width of 300px sets the width of the content only, and the padding and border are added on top, so the box ends up wider than 300px. Adding box-sizing: border-box; makes the width include padding and border, which is what most people expect. Many stylesheets start with * { box-sizing: border-box; }, where * matches every element.

Flexbox: lining things up in one direction

Flexbox lays items out along one line: a row or a column. You turn it on by giving the container (the parent) display: flex;. Its children, called flex items, now sit side by side. Then you control the line with a few properties. justify-content spreads items along the main direction (left to right in a row). align-items positions them across it (top to bottom in a row). gap adds space between items. flex-wrap: wrap; lets items drop to a new line when there is not enough room.

CSS
.cards {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
}

.card {
  padding: 12px;
  background-color: #eef7ee;
  border: 1px solid #1b5e20;
}
A row of cards: spaced evenly, centred vertically.
Diagram

Three boxes in a normal flow, then in a flex row with gaps.

Normal flow

display: flex

Three boxes in a normal flow, then in a flex row with gaps.
Read this figure as text

Two live mini pages showing three boxes stacked, then three boxes in a row after display flex is added.

Two live pages with the same three boxes labelled Seeds, Tools and Water. Before: the boxes are stacked one above the other, because no layout rule is applied. After: the container has display flex and a gap, so the three boxes sit in a single row with space between them.

Grid: rows and columns together

CSS Grid lays items out in two directions at once, like the squares of a timetable. Give the container display: grid; and describe the columns with grid-template-columns. The unit fr means a fraction of the free space, so 1fr 1fr 1fr makes three equal columns. Items fill the cells from left to right, then start a new row. gap works here too.

CSS
.gallery {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  gap: 12px;
}
A grid of three equal columns.
Diagram

Six boxes in a normal flow and in a three-column grid.

Normal flow

display: grid

Six boxes in a normal flow and in a three-column grid.
Read this figure as text

Two live mini pages showing six boxes stacked, then arranged in a grid of three columns and two rows.

Two live pages with the same six boxes numbered 1 to 6. Before: they are stacked in one column. After: the container has display grid with three equal columns and a gap, so boxes 1, 2 and 3 form the first row and boxes 4, 5 and 6 form the second row.

Choosing between Flexbox and Grid
QuestionFlexboxGrid
DirectionOne line: a row or a columnRows and columns together
Good forNavigation bars, rows of buttons, centring one thingPage layouts, galleries, card collections
Starts withThe content: items size themselvesThe layout: you plan the columns first
Turn on withdisplay: flex;display: grid;

The two tools combine well. A common pattern is a grid for the overall page and Flexbox inside each card or the navigation bar. You can try both in the live editor from the earlier lessons. Open it from the first CSS lesson, add display: flex; or display: grid; to a container and watch the boxes jump into place.

Experiments to try

  1. Step 1: Add padding

    Give a div a background colour and padding: 20px;.

    You should see: The coloured area grows around the text.

  2. Step 2: Add a margin

    Add margin: 20px; to the same div.

    You should see: The coloured area does not grow, but the space around it does.

  3. Step 3: Make a flex row

    Put three divs inside a container and add display: flex; gap: 12px; to the container.

    You should see: The three divs sit in a line.

  4. Step 4: Make a grid

    Change the container to display: grid; grid-template-columns: 1fr 1fr; with four divs inside.

    You should see: The divs form two columns and two rows.

Common mistakes

  • ✖ Instead of: Using margin to try to enlarge a coloured area around text.

    ✔ Do this: Use padding. Margin is outside the box and shows no background.

  • ✖ Instead of: Putting display: flex on the items instead of on their container.

    ✔ Do this: Flex and grid are set on the parent. The children then become flex or grid items.

  • ✖ Instead of: Confusing justify-content and align-items.

    ✔ Do this: In a row, justify-content works left to right and align-items works top to bottom. In a column the two swap roles.

  • ✖ Instead of: Setting fixed pixel heights so text overflows when someone enlarges it.

    ✔ Do this: Let height follow the content, or use min-height, so text can grow.

If something goes wrong

My flex items are still stacked in a column.
Check that display: flex; is on the parent container and that the selector actually matches it. Check for spelling mistakes too.
My box is wider than the page and a horizontal scrollbar appears.
Padding and border are being added to your width. Add box-sizing: border-box;, and avoid widths larger than 100%.
The grid has only one column.
You need grid-template-columns as well as display: grid. Without it, each row holds one item.
Vertical centring does nothing.
The container needs a height bigger than its content. Give it height or min-height, then use align-items: center;.

Key terms

Box model
The idea that every element is a rectangle made of content, padding, border and margin.
Flexbox
A CSS layout method that arranges items along one line, a row or a column.
CSS Grid
A CSS layout method that arranges items in rows and columns at the same time.

Practise it for real

Reading is not the same as being able to do it. Complete these on your own computer, then tick only what you have actually done. These ticks are your own honest record: nothing checks them for you.

Guided exercise

See the four layers

In the live editor create a div with some text. Give it a background colour, then change padding, border and margin one at a time, noting each time what moves in the preview. Finish by adding box-sizing: border-box; and a width of 300px.

You have succeeded when:
Guided exercise

A navigation bar and a gallery

Build a navigation bar of four links with Flexbox (gap, justify-content) and a gallery of six coloured boxes with Grid in three columns. Use fictional content only. Then change the grid to two columns and see how the rows rearrange.

You have succeeded when:
Independent challenge

Challenge: centre a card

Place a single card in the exact centre of the preview, both horizontally and vertically, using Flexbox on a container with a height of 300px. Do not ask for a recipe: use what you know about justify-content and align-items, and test your idea.

You have succeeded when:

Knowledge check

6 questions. You need 80% to pass. Mistakes here are part of learning, and you can retry as often as you like.

  1. Question 1.Put the layers of the box model in order from the content outwards.
    1. Margin
    2. Padding
    3. Border
    4. Content
  2. Question 2.You want more empty space between the text and the edge of its coloured background. What do you change?
  3. Question 3.With the default settings, a width: 300px box with padding and a border is exactly 300px wide in total.
  4. Question 4.Joseph wants five buttons in one row with equal space between them, and the row must wrap on a narrow screen.Which approach fits best?
  5. Question 5.Match each property to what it does.
  6. Question 6.Which job suits CSS Grid best?

Summary

  • Every element is a box: content, padding, border and margin.
  • Padding is inside the border and shows the background; margin is outside.
  • `box-sizing: border-box` makes width include padding and border.
  • Flexbox arranges items along one line; Grid arranges rows and columns together.
  • Both are switched on at the parent with `display`.

Checklist: can you do these?

Marking a lesson as read does not prove you can do it. Skills count as demonstrated when you pass the quiz (not yet) and complete the practical tasks (not yet).

Related lessons

References and further reading

Official sources for details that can change between versions.

On this page