Margin on child element moves parent element

  • Added:
  • |
  • In: Wordpress

I have a div (parent) that contains another div (child). Parent is the first element in body with no particular CSS style. When I set

.child { margin-top: 10px; } 

The end result is that top of my child is still aligned with parent. Instead of child being shifted for 10px downwards, my parent moves 10px down.

My DOCTYPE is set to XHTML Transitional.

What am I missing here?

edit 1
My parent needs to have strictly defined dimensions because it has a background that has to be displayed under it from top to bottom (pixel perfect). So setting vertical margins on it is a no go.

edit 2
This behaviour is the same on FF, IE as well as CR.

This Question Has 12 Answeres | Orginal Question | Robert Koritnik

Using top instead of margin-top is another possible solution, if appropriate.

An alternative solution I found before I knew the correct answer was to add a transparent border to the parent element.

Your box will use extra pixels though...

.parent { border:1px solid transparent; } 

The margin of the elements contained within .child are collapsing.

<html> <style type="text/css" media="screen"> #parent {background:#dadada;} #child {background:red; margin-top:17px;} </style> <body> <div id="parent"> <p>&amp;</p> <div id="child"> <p>&amp;</p> </div> </div> </body> </html> 

In this example, p is receiving a margin from the browser default styles. Browser default font-size is typically 16px. By having a margin-top of more than 16px on #child you start to notice it's position move.

I find out that, inside of your .css >if you set the display property of a div element to inline-block it fixes the problem. and margin will work as is expected.

I had this problem too but preferred to prevent negative margins hacks, so I put a

<div class="supercontainer"></div>

around it all which has paddings instead of margins. Of course this means more divitis but it's probably the cleanest way to do get this done properly.

the parent element has not to be empty at least put &nbsp; before the child element.

interestingly my favorite solution to this problem isn't yet mentioned here: using floats.


<div class="parent"> <div class="child"></div> </div> 


.parent{width:100px; height:100px;} .child{float:left; margin-top:20px; width:50px; height:50px;} 

see it here:

note that in case you need dynamic height on the parent, it also has to float, so simply replace height:100px; by float:left;

Found an alternative at Child elements with margins within DIVs You can also add:

.parent { overflow: auto; } 


.parent { overflow: hidden; } 

This prevents the margins to collapse. Border and padding do the same. Hence, you can also use the following to prevent a top-margin collapse:

.parent { padding-top: 1px; margin-top: -1px; } 

Update by popular request: The whole point of collapsing margins is handling textual content. For example:

<style type="text/css"> h1, h2, p, ul { margin-top: 1em; margin-bottom: 1em; } </style> <h1>Title!</h1> <div class="text"> <h2>Title!</h2> <p>Paragraph</p> </div> <div class="text"> <h2>Title!</h2> <p>Paragraph</p> <ul> <li>list item</li> </ul> </div> 

Because the browser collapses margins, the text would appear as you'd expect, and the <div> wrapper tags don't influence the margins. Each element ensures it has spacing around it, but spacing won't be doubled. The margins of the <h2> and <p> won't add up, but slide into each other (they collapse). The same happens for the <p> and <ul> element.

Sadly, with modern designs this idea can bite you when you explicitly want a container. This is called a new block formatting context in CSS speak. The overflow or margin trick will give you that.

This is normal behaviour (among browser implementations at least). Margin does not affect the child's position in relation to its parent, unless the parent has padding, in which case most browsers will then add the child's margin to the parent's padding.

To get the behaviour you want, you need:

.child { margin-top: 0; } .parent { padding-top: 10px; } 

This is what worked for me

.parent { padding-top: 1px; margin-top: -1px; } .child { margin-top:260px; }

add style display:inline-block to child element

Although all of the answers fix the issue but they come with trade-offs/adjustments/compromises like

  • floats, You have to float elements
  • border-top, This pushes the parent at least 1px downwards which should then be adjusted with introducing -1px margin to the parent element itself. This can create problems when parent already has margin-top in relative units.
  • padding-top, same effect as using border-top
  • overflow: hidden, Can't be used when parent should display overflowing content, like a drop down menu
  • overflow: auto, Introduces scrollbars for parent element that has (intentionally) overflowing content (like shadows or tool tip's triangle)

The issue can be resolved by using CSS3 pseudo elements as follows

.parent::before { clear: both; content: ""; display: table; margin-top: -1px; height: 0; }

I am...

Sajjad Hossain

I have five years of experience in web development sector. I love to do amazing projects and share my knowledge with all.

Are you searching for Good Quality hosting?
You can Try It!
Connect Social With PHPAns