The CSS Box Model: Content, Padding, Border and Margin
Learn how every element is a box made of content, padding, border and margin, how to size and space it, and how box-sizing changes the maths.
What you will learn
Here is the most important idea in CSS layout: every element on a web page is a rectangular box. Headings, paragraphs, images, buttons, even a single <span>: all boxes. Once you understand how these boxes are built, spacing and sizing stop being guesswork. In this lesson you will learn the four layers of the box (content, padding, border and margin), how to set each one, how to centre a box, and how box-sizing changes the width you get.
The four layers of a box
Every box has four layers, from the inside out:
- Content: the text, image or other stuff inside.
- Padding: empty space between the content and the border, inside the box.
- Border: a line around the padding.
- Margin: empty space outside the border, which pushes other boxes away.
+----------------------- margin -----------------------+
| |
| +-------------------- border --------------------+ |
| | | |
| | +---------------- padding -----------------+ | |
| | | | | |
| | | CONTENT | | |
| | | (text, images, etc.) | | |
| | | | | |
| | +------------------------------------------+ | |
| | | |
| +------------------------------------------------+ |
| |
+------------------------------------------------------+
A good picture to remember: a framed photo on a wall.
- The photo is the content.
- The white mat around the photo is the padding.
- The frame is the border.
- The empty wall space between this frame and the next one is the margin.
Two facts that trip people up:
- The element’s background colour fills the content and the padding (and goes under the border), but never the margin. Margin is always transparent.
- Padding is part of the box and margin is not. Clicking on the padding clicks the element, but clicking in the margin does not.
The HTML we will style
The practice page for this lesson is deliberately simple:
<h1 class="page-title">Box Model Lab</h1>
<div class="box" id="box-one">Box one</div>
<div class="box" id="box-two">Box two</div>
<div class="banner">I am centered with margin: 0 auto</div>
<div class="size-demo content-demo">content-box</div>
<div class="size-demo border-demo">border-box</div>
| Selector | Matches this element | Used for |
|---|---|---|
.box |
both <div>s that have the class box |
learning width, padding, border and margin |
#box-one, #box-two |
the two individual boxes (each has a unique id) |
styling one box differently |
.banner |
the <div> with the centred text |
centring with margin: 0 auto |
.size-demo |
the last two <div>s |
the shared look for the box-sizing demo |
.content-demo |
the first .size-demo |
box-sizing: content-box |
.border-demo |
the second .size-demo |
box-sizing: border-box |
Setting width and height
width and height size the content area by default:
.box {
width: 200px;
background-color: lightblue;
}
Block elements such as <div> and <p> are as wide as their parent unless you set a width. Their height comes from their content, so you rarely need to set height. Fixed heights can make text overflow when the content grows.
You can also limit the size without fixing it:
max-width: 600pxmeans “as wide as needed, but never wider than 600px”.min-height: 200pxmeans “at least 200px tall, but grow if needed”.
Padding: space inside the box
.box {
width: 200px;
padding: 20px;
background-color: lightblue;
}
The box now has 20px of breathing room on all four sides between the text and the edge. Padding can be set per side:
.box {
padding-top: 10px;
padding-right: 20px;
padding-bottom: 10px;
padding-left: 20px;
}
The shorthand: one, two, three or four values
Instead of four lines you can use the padding shorthand. The number of values changes the meaning:
padding: 20px; /* all four sides */
padding: 10px 30px; /* top and bottom | left and right */
padding: 10px 30px 20px; /* top | left and right | bottom */
padding: 10px 30px 20px 40px; /* top | right | bottom | left */
With four values you go clockwise, starting at the top: top, right, bottom, left. A memory trick is the word TRouBLe: Top, Right, Bottom, Left. margin and border-width use exactly the same pattern.
Padding cannot be negative.
Border: the edge of the box
The border shorthand takes three things: the width, the style and the colour:
.box {
border: 5px solid steelblue;
}
- Width:
5px(orthin,medium,thick). - Style:
solid,dashed,dotted,doubleornone. Without a style there is no border, even if you set a width and colour. - Colour: any CSS colour.
You can also set one side only:
.box {
border-bottom: 3px dashed crimson;
}
Borders have their own dedicated lesson later, where you will also round their corners.
Margin: space outside the box
Margin pushes neighbouring boxes away. It uses the same one-to-four value shorthand as padding:
.box {
margin: 15px; /* 15px on all sides */
}
#box-two {
margin-top: 40px; /* only the second box gets extra space above it */
}
Compared with padding, margin:
- sits outside the border and the background;
- can be negative (it pulls elements closer or makes them overlap, which is rarely a good idea);
- can be
auto, which is how you centre things.
Centring a box with margin: 0 auto
The classic way to centre a block element horizontally is to give it a width and set its left and right margins to auto:
/* the <div class="banner"> */
.banner {
width: 300px;
margin: 0 auto;
background-color: gold;
text-align: center;
}
0 auto means “0 top and bottom, and auto left and right”. The browser shares the leftover space equally on both sides. Two rules: it only works if the element has a width (otherwise it already fills the whole row) and it only works horizontally.
How wide is a box really?
With the default behaviour, the width you write is only the content width. Padding and border are added on top. Here is the maths for our box:
.box {
width: 200px;
padding: 20px;
border: 5px solid steelblue;
margin: 15px;
}
| Part | Left + right |
|---|---|
| content | 200px |
| padding | 20 + 20 = 40px |
| border | 5 + 5 = 10px |
| visible box width | 250px |
| margin | 15 + 15 = 30px |
| space it takes up | 280px |
So a box written as width: 200px actually appears 250px wide. That surprises almost every beginner. Open DevTools and hover over the box to see this diagram yourself.
box-sizing: getting the width you wrote
The box-sizing property changes what width means:
content-box(the default):widthis the content only. Padding and border are added outside.border-box:widthincludes the content, the padding and the border.
Try both with Try it:
/* both <div class="size-demo"> boxes */
.size-demo {
width: 200px;
padding: 20px;
border: 5px solid navy;
background-color: lightblue;
margin-bottom: 10px;
}
/* the first one keeps the default behaviour */
.content-demo {
box-sizing: content-box; /* visible width: 250px */
}
/* the second one includes padding and border in its width */
.border-demo {
box-sizing: border-box; /* visible width: 200px */
}
Both boxes have exactly the same width, padding and border, but the second one is visibly narrower. With border-box, the content shrinks to 200 - 40 - 10 = 150px so that the total stays 200px.
border-box is much easier to work with: if you say width: 200px, you get a 200px box, whatever padding you add later. Almost every modern site turns it on for all elements. The next lesson shows how.
Putting it together
.page-title {
margin-bottom: 20px;
}
.box {
width: 200px;
padding: 20px;
border: 5px solid steelblue;
margin: 15px;
background-color: lightblue;
box-sizing: border-box;
}
#box-two {
background-color: lightgreen;
border-color: seagreen;
margin-top: 40px;
}
.banner {
width: 300px;
margin: 0 auto;
padding: 12px;
background-color: gold;
text-align: center;
}
Common mistakes
- Forgetting the border style.
border: 5px steelblueshows nothing, because the style (solid) is missing. - Being surprised by the wider box. Padding and border add to
widthincontent-boxmode. Usebox-sizing: border-box. - Mixing up padding and margin. Ask yourself: should the background cover the gap? Yes: padding. No: margin.
- Trying
margin: 0 autowithout a width, or on an inline element such as<span>. - Getting the shorthand order wrong. Four values go clockwise from the top.
- Fixing the
heightof text boxes. When the content grows, it overflows the box. Prefermin-heightor padding. - Using margin for space inside a box. The background will not cover it.
Practice
- Click Practice in Editor. Change the
.boxpadding to40px, then to10px 40px. Watch the background grow and shrink around the text. - Give
#box-twoa different border colour andmargin-top: 40px, without touching#box-one. - Centre the
.banner. Then remove itswidthand observe what happens to the centring. - Add
.content-demoand.border-demorules and measure both boxes in DevTools. Confirm 250px and 200px. - Use the DevTools box diagram to find the exact content width of
.boxwhenbox-sizing: border-boxis on. - Predict the total width (content + padding + border) of a box with
width: 300px; padding: 10px 20px; border: 2px solid red;incontent-boxmode, then check it in DevTools.
Recap
- Every element is a box with four layers: content, padding, border and margin.
- Padding is space inside (and gets the background). Margin is space outside (and is transparent).
padding,marginandborder-widthaccept 1 to 4 values; four values go clockwise: top, right, bottom, left.borderneeds a width, style and colour. No style means no border.margin: 0 autocentres a block element that has a width.- By default
widthonly sizes the content. Withbox-sizing: border-boxit includes padding and border, which is easier to predict. - Next you will learn how to apply
border-boxto your whole site and how CSS resets work.