41

I have a problem with the margin-top in a nested div -- when I apply margin-top to the nested div, the margin is applied to the parent div instead of the nested div.

Any ideas?

Ian Campbell
  • 2,678
  • 10
  • 56
  • 104
JuanPablo
  • 23,792
  • 39
  • 118
  • 164
  • in some cases you could also try padding-top:40px just for testing. You can also use padding-top:40px !important; – Junior Mayhé May 23 '10 at 01:19
  • It seems to be one of gazillions of examples of CSS doing what it's supposed to. However, what it's supposed to do it utterly counter-intuitive. – nicodemus13 Apr 18 '14 at 09:43
  • A very nice explanation why it happens and how to work with it. http://www.sitepoint.com/web-foundations/collapsing-margins/ – sidneydobber Nov 13 '14 at 07:45
  • Possible duplicate of [Why does this CSS margin-top style not work?](http://stackoverflow.com/questions/9519841/why-does-this-css-margin-top-style-not-work) – Pavel Gatnar Apr 12 '16 at 12:00

6 Answers6

53

I get the solution with overflow:auto in the parent div.

JuanPablo
  • 23,792
  • 39
  • 118
  • 164
32

Margins will collapse by design. Add 1px of padding as well and it should work fine.

edl
  • 3,194
  • 22
  • 23
  • 3
    This has quite an acceptable explanation: http://www.howtocreate.co.uk/tutorials/css/margincollapsing – Frank N Apr 09 '13 at 13:18
17

This is how margins work.. the margin is the space between the next element with a margin / padding / similar. It is not necessarily defined as its parent element. Consult the spec.

Here are some things you can do as a workaround

Use Padding Instead

This just means instead of using margin-top: 10px; you use padding-top: 10px;. This is not suitable for every occasion.

Weird Hack I Discovered

I doubt I discovered this initially, but the other day I solved the problem like this. I had a <div id="header" /> that I wanted to give a top margin too, and its top margin was pushing the parent (body element) down as well. So I did this on the body element...

body {
    padding-top: 1px;
    margin-top: -1px;
}

This made my margin work. You can also try using a border, like border: 1px solid #ccc.

It would also be wise to leave a note in the CSS comments to explain why you have that peculiar pair of rules. I just added /* this is to stop collapsing margins */.

Further Reading

Check out these other questions on Stack Overflow

Community
  • 1
  • 1
alex
  • 479,566
  • 201
  • 878
  • 984
7

The reason overflow:auto changes the parent div to allow the nested margin-top is that it creates a new formatting context. Any div that's positioned absolute, fixed, floated or with overflow other than visible creates a new formatting context. The parent div then becomes the root of this new formatting context, and collapsing margins don't apply to root elements.

More in depth:

Formatting contexts can be either inline or block, and only the block formatting contexts collapse their margins. These formatting contexts form the flow of the document.

A block formatting context is simply all the block level elements (e.g. divs, p, table) laid out one after another vertically within a containing block until the end of the document/container or until a new formatting context is established.

In the case of nesting, the margin-top of the child collapses with the margin-top of the parent since both divs are part of a block formatting context. By setting overflow to auto, the parent div becomes the container of the new formatting context, and the child the first block element within it. Thus the two margins are no longer "adjoining" since the parent div is now the root.

Hope that helps.

Box model: http://www.w3.org/TR/CSS2/box.html#collapsing-margins

Visual formatting model: http://www.w3.org/TR/CSS2/visuren.html#normal-flow

pfrendly
  • 311
  • 2
  • 4
4

"Collapsing margins" is your problem. Here you could understand what is and why it's still alive: http://www.sitepoint.com/web-foundations/collapsing-margins/

I read across the web to look for a decent solution, and finally I found this article: http://www.seifi.org/css/understanding-taming-collapsing-margins-in-css.html

In short you have a bunch of methods to resolve your problem:

1) border in parent div (could be transparent)

2) padding in parent div

3) overflow: auto

4) float: left

You should follow the link because it explains in detail all the solutions.

LucaM
  • 799
  • 1
  • 10
  • 21
0

You Can also use position property for inner div to fix this. like:

position:fixed;
shadow
  • 29
  • 1
  • 7