The CSS margin property
Margin is the space outside an element's border. It pushes neighbors away and is always transparent, so whatever sits behind the element shows through. In this lesson the buttons get a little room on the right and below, and the whole row gets room from the edge of the page.
Adding margin
Fill in the empty .btn rule from lesson 1 and add a rule for the row above it:
/* Lesson 2: space around the whole row */
.btn-row {
margin: 2rem 1rem;
}
.btn {
/* Lesson 2: margin */
margin: 0 0.5rem 0.5rem 0;
}
The unit rem is relative to the root font size, the font size of the <html> element. Unless the reader or the page changes it, that is 16px, so 0.5rem is 8px and 2rem is 32px. Spacing in rem grows along with the default font size a reader picks in their browser settings, which a fixed px value would ignore.
The shorthand, value by value
margin is a shorthand for four properties: margin-top, margin-right, margin-bottom and margin-left. How many values you write decides which sides they go to.
| You write | Top | Right | Bottom | Left |
|---|---|---|---|---|
margin: 1rem; |
1rem | 1rem | 1rem | 1rem |
margin: 2rem 1rem; |
2rem | 1rem | 2rem | 1rem |
margin: 1rem 2rem 3rem; |
1rem | 2rem | 3rem | 2rem |
margin: 0 0.5rem 0.5rem 0; |
0 | 0.5rem | 0.5rem | 0 |
With four values the order runs clockwise from the top: top, right, bottom, left. If you need a memory aid, "TRouBLe" spells it out. A zero needs no unit, since zero pixels and zero rem are the same distance.
Writing a single side is also allowed, and it is clearer when only one side matters:
.btn {
margin-right: 0.5rem;
margin-bottom: 0.5rem;
}
That is exactly what our four-value line does. We keep the shorthand because the project's final code reads better with one line per property group.
What the browser does with it
Reload and look closely. The row moves away from the top and left edges of the window. The <p> is a block element, and blocks honor margin on all four sides. Its new 2rem also replaces the 1em top and bottom margin that browsers give paragraphs by default.
The buttons are less obedient. The two links gain space on their right, and that is all. A link is an inline element, a piece of text flow like a word in a sentence, and MDN says it plainly: top and bottom margins "have no effect on non-replaced inline elements". The <button> is different. Browsers display it as inline-block, so its bottom margin does count. The difference is hard to spot while all three fit on one line, and it shows once they wrap onto a second line on a narrow screen.
This mismatch is not a bug in your CSS. Lesson 10, the display property, switches the links to display: inline-block, and from then on all three elements treat margin the same way. Leaving the declaration in place now means the spacing is ready when that happens.
Why only right and bottom?
Margin on all four sides of every button would double up between neighbors (0.5rem from one plus 0.5rem from the next) and add a stray half gap at the start of the row. With margin on the right and bottom only, every gap between two buttons is one 0.5rem margin, and wrapped lines get the same 0.5rem between them.
There is one extra gap you did not write: the space characters between the tags in the HTML. Inline and inline-block elements sit in a line of text, so the line break between </a> and the next <a> renders as one space, about a quarter of the font size wide. It is harmless here. Lesson 10 shows a layout mode that ignores it.
Common questions
Can margin be negative?
Yes. A negative margin pulls an element toward its neighbors or even over them. It has uses in layout tricks and none in this project. Padding, the next lesson, cannot be negative at all.
What does margin: auto do?
On a block element with a set width, margin: 0 auto splits the leftover horizontal space between left and right, which centers the block. Centering comes back in Project 2 when it centers the menu links.
Why did two stacked paragraphs not get the sum of their margins?
Vertical margins between block elements collapse. When a bottom margin of 2rem meets a top margin of 1rem, the gap is 2rem, the larger of the two, not 3rem. Margins of inline-block boxes and of flex items never collapse, which is one reason button rows rarely surprise you.
Try it: in the online HTML editor, change the .btn margin to 1rem, then to 0 2rem, and watch which gaps change and which stay put.