The margin
property defines the outermost portion of the box model, creating space around an element, outside of any defined borders.
Margins are set using lengths, percentages, or the keyword auto
and can have negative values. Here’s an example:
.box {
margin: 0 3em 0 3em;
}
margin
is a shorthand property and accepts up to four values, shown here:
.box {
margin: <margin-top> || <margin-right> || <margin-bottom> || <margin-left>
}</margin-left></margin-bottom></margin-right></margin-top>
If fewer than four values are set, the missing values are assumed based on the ones that are defined. For example, the following two rule sets would get identical results:
.box {
margin: 0 1.5em;
}
.box {
margin: 0 1.5em 0 1.5em;
}
Thus, if only one value is defined, this sets all four margins to the same value. If three values are declared, it is margin: [top] [left-and-right] [bottom];
.
Any of the individual margins can be declared using longhand, in which case you would define only one value per property:
.box {
margin-top: 20px;
margin-right: 10px;
margin-bottom: 20px;
margin-left: 10px;
}
auto
and centering
Each of the margin properties can also accept a value of auto
. A value of auto
basically tells the browser to define the margin for you. In most cases, a value of auto
will be equivalent to a value of 0
(which is the initial value for each margin property) or else whatever space is available on that side of the element. However, auto
is handy for horizontal centering:
.container {
width: 980px;
margin: 0 auto;
}
In this example, two things are done to center this element horizontally within the available space:
- The element is given a specified width
- The left and right margins are set to
auto
Without the specified width, the auto
values would essentially have no effect, setting the left and right margins to 0
or else to whatever is the available space inside the parent element.
It should also be pointed out that auto
is useful only for horizontal centering, and so using auto
for top and bottom margins will not center an element vertically, which can be confusing for beginners.
Collapsing margins
Vertical margins on different elements that touch each other (thus have no content, padding, or borders separating them) will collapse, forming a single margin that is equal to the greater of the adjoining margins. This does not happen on horizontal margins (left and right), only vertical (top and bottom).
To illustrate, take the following HTML:
<h2>Collapsing Margins</h2>
Example text.
And the following CSS:
h2 {
margin: 0 0 20px 0;
}
p {
margin: 10px 0 0 0;
}
In this example, the h2
element is given a bottom margin of 20px. The paragraph element, which immediately follows it in the source, has a top margin set at 10px.
Common sense would seem to suggest that the vertical margin thickness between the h2
and the paragraph would be a total of 30px (20px + 10px). But due to margin collapse, the actual thickness ends up being 20px. This is demonstrated in the embedded pen below:
Check out this Pen!
Although collapsing margins may seem unintuitive at first glance, they are actually useful for a few reasons. First, they prevent empty elements from adding extra, usually undesirable, vertical margin space.
Second, they allow for a more consistent approach to declaring universal margins across page elements. For example, headings commonly have vertical margin space, and so do paragraphs. If margins didn’t collapse, headings that follow paragraphs (or vice-versa) would often require resetting the margins on one of the elements in order to achieve a consistent amount of vertical spacing.
Third, margin collapse also applies to nested elements. Look at the following pen:
Check out this Pen!
Here, the paragraph element has a top margin set at 30px, and is nested inside a div
element with a top margin of 40px. In addition, the h2
element has a bottom margin of 20px.
Again, common sense would suggest that the total vertical margin space here would be 90px (20px + 40px + 30px), but instead the margins all collapse into a single 40px margin (the highest of the three). This is helpful in most cases since there is no need to redefine any of the top margins to remove the extra vertical space.
Negative Margins
As you might suspect, while a positive margin value pushes other elements away, a negative margin will either pull the element itself in that direction, or pull other elements toward it.
Here’s an example of a container with padding, and the header h2 has negative margins pulling itself through that padding back to the edges:
See the Pen
Most Common Use Case for Negative Margins by Chris Coyier (@chriscoyier)
on CodePen.
Here’s an example where the first paragraph has a negative bottom margin, which pulls the next paragraph up against.
See the Pen
Negative Margin pulling bottom paragraph by Chris Coyier (@chriscoyier)
on CodePen.
Related Properties
Other Resources
Browser Support
Chrome | Safari | Firefox | Opera | IE | Android | iOS |
---|---|---|---|---|---|---|
Works | Works | Works | Works | Works | Works | Works |
IE6 is prone to the doubled float-margin bug, which can be resolved in most cases by adding display: inline
to the floated element.
And how is this-“It should also be pointed out that auto is useful only for horizontal centering, and so using auto for top and bottom margins will not center an element horizontally, which can be confusing for beginners.”, not confusing to beginners?
I think Ruksun, that it is meant to say “vertical” instead of “horizontal”. If possible that could be changed so as not to confuse a newer designer. :)
“It should also be pointed out that auto is useful only for horizontal centering, and so using auto for top and bottom margins will not center an element vertically, which can be confusing for beginners.”
Since the order of the margin selector values is top > right > bottom > left, why does placing 0 auto make top + bottom 0 and left + right auto? Shouldn’t that keep bottom at whatever default value (assuming it’s not 0)?
Livia, just giving two values will result in the first value being used for top and bottom and the second value being used for left and right. If you just set one value it will be used on all (top, bottom, left, right). In both cases margin values that are set before, will be overwritten.
More information about margin on mozilla developer network
You are wonderful chris.
“This is helpful in most cases since there is no need to redefine any of the top margins to remove the extra vertical space.”
I always looked at the collapsing margin as a bug. But you can totally rock this to your advantage especially when building flexible theme layouts where the sequence of elements my change.
I can’t believe I have only just realised this…
“A whole new world… A hundred thousand th…”
Silly question (css comment about margin-right) but answer me please. http://codepen.io/dagolinuxoid/pen/wazPJJ
Already easy got it.Definitely it was my biggest css ahaha moment, unfortunately I can’t delete this post above, what a shame))
Very Nice tutorial.
Very useful tips. Btw, I have tested the collapse margins and I noticed that when I used same elements, it will NOT collapse. Meaning if we take two image tags “<img…”, and apply the same CSS as mentioned in the example given in this article (p, h2 tags), it will not collapse. See examples below:
EXAMPLE-1(NO Collapse):
HTML:
CSS:
This code above will result in a 30px margin (20+10).
EXAMPLE-2(Collapse- same example given in this article):
HTML:
CSS:
This will result in a 20px margin (the higher margin).
Please let me know if I am missing something here. Thank you
Moath, remove the
<br>
and make the img tags bedisplay:block;
and it’ll fix your double margins. Ideally, you wouldn’t margin your image and you would instead margin its wrapper (like if you stuck the image in a<figure>
).I have already listen and implement about “margin” property in css but I didn’t understand about these…
“margin-block-start”, “margin-block-end”, “margin-inline-start”, “margin-inline-end” in css. What are the purpose of these? And can you please show a demo so we can easily understand it. Thanks.
References:
https://developer.mozilla.org/en-US/docs/Web/CSS/Reference
https://developer.mozilla.org/en-US/docs/Web/CSS/margin-block-end
Can you please explain to me this paragraph:
“If fewer than four values are set, the missing values are assumed based on the ones that are defined. For example, the following two rule sets would get identical results:
Are these two supposed to do the same? Because that is not correct. Or am I not reading this correctly?
Yes, these two are supposed to do the same, because in the first rule set value 0 is used for top and bottom margin while 1.5em is used for left and right margin.
In the second rule set these values are defined explicitly.
Remember the order of values: top right bottom left.
This is beautiful