Say you've got a collection of three boxes, stacked on top of each other and you want space between them. How many ways can you think of to do that in CSS?
margin property might give you what you need,
but it also might add additional spacing that you don't want.
For example, how do you target just the space in between each of those elements?
gap might be more appropriate in this case.
There are many ways to adjust spacing within a UI,
each with its own strengths and caveats.
HTML itself provides some methods to space elements.
<hr> elements allow you to space elements in the block direction,
which if you are in a latin-based language,
If you use a
it will create a line-break,
just like if you were to press your enter key in a word processor.
<hr> creates a horizontal line with space either-side, known as
Along with using HTML elements,
HTML entities can create space.
An HTML entity is a reserved string of characters that are replaced with character entities by the browser.
if you were to type
© in your HTML file,
it would be converted into a © character.
entity is converted into a non-breaking space character,
which provides an inline space.
Be careful though,
because the non-breaking aspect of this character stitches the two elements together,
which can result in odd behaviour.
If you want to add space to the outside of an element,
you use the
Margin is like adding a cushion around your element.
margin property is shorthand for
margin shorthand applies properties in a particular order:
top, right, bottom and left.
You can remember these with trouble: TRouBLe.
margin shorthand can also be used with one, two, or three values.
Adding a fourth value lets you set each individual side.
These are applied as follows:
- One value will be applied to all sides. (
- Two values: the first value will be applied to the top and bottom sides,
and the second value will be applied to the left and right sides.
margin: 20px 40px)
- Three values: the first value is
top, the second value is
right, and the third value is
margin: 20px 40px 30px).
Margin can be defined with a length,
percentage or auto value, such as
If you use a percentage,
the value will be calculated based on the width of your element's containing block.
This means that if your element's containing block has a width of
and your element has a
margin value of
each side of your element will have a computed margin of
You can also use a value of
auto for margin.
For block level elements with a restricted size,
auto margin will take up available space in the direction that it is applied to.
A good example is this one,
from the flexbox module, where the items push away from each other.
Another good example of
auto margin is a horizontally centered wrapper which has a max width.
This sort of wrapper is often used to create a consistent center column on a website.
margin: 0 auto;
Here, margin is removed from the top and bottom (block) sides,
auto shares the space between the left and right (inline) sides.
Negative values can also be used for margin. Instead of adding space between adjacent sibling elements, it will reduce space between them. This can result in overlapping elements, if you declare a negative value that's more than the available space.
Margin collapse is a tricky concept, but it's something you'll run into very commonly when building interfaces. Say you have two elements: a heading and a paragraph that both have vertical margin on them:
<h1>My heading with teal margin</h1>
<p>A paragraph of text that has blue margin on it, following the heading with margin.</p>
At first glance,
you would be forgiven for thinking that the paragraph will be spaced
5em from the heading,
3rem combined calculate to
Because vertical margin collapses, though, the space is actually
Margin collapse works by selecting the largest value of two adjoining elements
with vertical margin set on the adjoining sides.
The bottom of the
h1 meets the top of the
so the largest value of the
h1's bottom margin and the
p's top margin is selected.
h1 were to have
3.5rem of bottom margin,
the space between them both would then be
3.5rem because that is larger than
Only block margins collapse, not inline (horizontal) margins.
Margin collapse also helps with empty elements.
If you have a paragraph that has a top and bottom margin of
it will only create
20px of space: not
If anything is added to the inside of this element though,
padding, its margin will no longer collapse in itself and will be treated as any box with content.
Check your understanding
Test your knowledge of margin collapsing
If two elements stacked on top of each other both have 20px of top margin and 30px of bottom margin, how much space will there be between them?
Preventing margin collapse
If you make an element absolutely positioned,
position: absolute, the margin will no longer collapse.
The margin also won't collapse if you use the
float property, too.
If you have an element with no margin between two elements with block margin, the margin won't collapse either, because the two elements with block margin are no longer adjacent siblings: they are just siblings.
In the layout lesson, you learned that flexbox and grid containers are very similar to block containers, but handle their child elements very differently. This is the case with margin collapse, too.
If we take the original example from the lesson and apply flexbox with column direction, the margins are combined, instead of collapsed. This can provide predictability with layout work, which is what flexbox and grid containers are designed for.
Margin and margin collapse can be tricky to understand, but understanding how they work, in detail, is very useful, so this detailed explainer is strongly recommended.
Instead of creating space on the outside of your box,
padding property creates space on the inside of your box instead:
Depending on which box model you are using—which was covered back in the
box model lesson
padding can also affect the overall dimensions of the element too.
padding property is shorthand for
padding has logical properties, too:
Also covered in the layout module,
if you set a value for
position that is anything other than
you can space elements with the
There are some differences with how these directional values behave:
- An element with
position: relativewill maintain its place in the document flow, even when you set these values. They will be relative to your element's position too.
- An element with
position: absolutewill base the directional values from the relative parent's position.
- An element with
position: fixedwill base the directional values on the viewport.
- An element with
position: stickywill only apply the directional values when it is in its docked/stuck state.
In the logical properties module,
you learn about the
which allow you to set directional values that honor writing mode.
Both properties are shorthands combining the
and as such accept either one value to be set for
two individual values.
Grid and flexbox
Lastly, in both grid and flexbox you can use the
gap property to create space between child elements.
gap property is shorthand for
it accepts one or two values, which can be lengths or percentages.
You can also use keywords such as
If you define only one value,
gap will be applied to both the rows and columns,
but if you define both values,
the first value is
row-gap and the second value is
Creating consistent spacing
It is a really good idea to choose a strategy and stick with it to help you create a consistent user interface that has good flow and rhythm. A good way to achieve this is use consistent measures for your spacing.
For example, you could commit to using
as a consistent measure for all gaps between elements—known as gutters—so
all layouts look and feel consistent.
You could also decide to use
1em as the vertical spacing between flow content,
which would achieve consistent spacing based on the element's
Whatever you choose,
you should save these values as variables (or CSS custom properties)
to tokenize those values and make the consistency a bit easier.
Using custom properties like this allows you to define them once, then use them throughout your CSS. When they are updated, either locally within an element or globally, the values will pass down through the cascade and the updated values will be reflected.
Check your understanding
Test your knowledge of spacing
It's safe to use HTML for spacing when...
To create space inside a box, use...
To create space outside a box, use...
To create space between boxes, use...