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.
Outside
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.
.card {
padding: 16px;
border: 2px solid #1b5e20;
margin: 24px;
background-color: #eef7ee;
}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.
.cards {
display: flex;
justify-content: space-between;
align-items: center;
gap: 12px;
}
.card {
padding: 12px;
background-color: #eef7ee;
border: 1px solid #1b5e20;
}Normal flow
display: flex
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.
.gallery {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
gap: 12px;
}Normal flow
display: 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.
| Question | Flexbox | Grid |
|---|---|---|
| Direction | One line: a row or a column | Rows and columns together |
| Good for | Navigation bars, rows of buttons, centring one thing | Page layouts, galleries, card collections |
| Starts with | The content: items size themselves | The layout: you plan the columns first |
| Turn on with | display: 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
Step 1: Add padding
Give a div a background colour and
padding: 20px;.You should see: The coloured area grows around the text.
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.
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.
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
marginto 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: flexon 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-contentandalign-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-columnsas well asdisplay: grid. Without it, each row holds one item. - Vertical centring does nothing.
- The container needs a height bigger than its content. Give it
heightormin-height, then usealign-items: center;.
Key terms
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.
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.
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.
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.
Knowledge check
6 questions. You need 80% to pass. Mistakes here are part of learning, and you can retry as often as you like.
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.
- The box model (MDN Web Docs)
- Flexbox (MDN Web Docs)
- CSS grid layout (MDN Web Docs)