Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Margin on child element moves parent element

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.

like image 339
Robert Koritnik Avatar asked Nov 19 '09 11:11

Robert Koritnik


People also ask

Why does child margin affect parents?

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. The margin doesn't add to the padding... it applies separately. But the visual effect is the same.

What does the margin element do?

Margins are used to create space around elements, outside of any defined borders. This element has a margin of 70px.

Can we set the margins for an element?

Answer: You can set the margin property to auto to horizontally center the element within its container. The element will then take up the specified width, and the remaining space will be split equally between the left and right margins.


2 Answers

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; } 
like image 24
Ben James Avatar answered Oct 30 '22 12:10

Ben James


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

.parent { overflow: auto; } 

or:

.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; } 

2021 update: if you're willing to drop IE11 support you can also use the new CSS construct display: flow-root. See MDN Web Docs for the whole details on block formatting contexts.


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

h1, h2, p, ul {   margin-top: 1em;   margin-bottom: 1em;   outline: 1px dashed blue; }  div { outline: 1px solid red; }
<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.

like image 73
vdboor Avatar answered Oct 30 '22 11:10

vdboor