Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is setting the top-margin of this child element pushing its parent container down with it?

Tags:

html

css

I have two divs:

<div id="headercontainer" data-type="background" data-speed="5"> 
    <div id="headersubcontainer">
        <h1>Simple and Cost Effective Web Solutions</h1>  
    </div> 
</div>

<div id="teamcontainer" data-type="background" data-speed="5"> 
    <div id="teamsubcontainer"> 
        <h1>Developed by a dedicated team</h1> 
    </div> 
</div> 

both have 100% widths and heights of 800px. The first heading I have set a top-margin: of 160px. Instead of moving the header lower into its parent div, it moves the parent div down with it as you can see in this picture:

webpage

Here is my relevant css:

h1{
    font-size: 48px;
    font-family: $header-font-stack; 
    font-weight: 100;
    width: 400px;
}

#headercontainer{
    width: 100%; 
    height: 800px;
    background-image: image-url("background.jpg");
    background-position: center top;
    background-repeat: no-repeat;
}

#headercontainer h1{
    text-align: center;
    margin: 0px auto;
    margin-top: 160px;
    color: #610B21;
}

Using a padding works obviously, but I would like to be more proper and use a margin. How can set a top margin and move the heading lower into the container without moving the container with it?

like image 691
Sam D20 Avatar asked May 21 '14 15:05

Sam D20


4 Answers

This is due to margin collapsing:

Top and bottom margins of blocks are sometimes combined (collapsed) into a single margin whose size is the largest of the margins combined into it, a behavior known as margin collapsing.

This is resulting in the parent element reverse-inheriting the child element top margin.

You can prevent this by adding &nbsp; before the child element

Demo Fiddle

....or applying any of the below to the parent:

  1. float: left / right
  2. position: absolute
  3. display: inline-block

Adding display:inline-block; to the parent likely being the preference if it is set to have a width to 100%

Demo Fiddle

like image 195
SW4 Avatar answered Nov 10 '22 12:11

SW4


just use box-sizing: border-box; on the parent and set the padding there instead of margin-top. It will help you keep consistent spacing on all sides anyways

JSFIDDLE

like image 45
jmore009 Avatar answered Nov 10 '22 14:11

jmore009


Just add some top-padding to the parent element. even 1px and it will fix it.

like image 35
xatzistnr Avatar answered Nov 10 '22 12:11

xatzistnr


I would actually argue that this answer is better:

https://stackoverflow.com/a/49075574/2387316

Yes, I know it's my own answer, but I think it's important that we don't add random bits of padding, change box-sizing for no reason, add spurious elements to the DOM, or change display/padding simply to fix a display issue. Those solutions all cause problems on their own: SEO is worse, unpredictable box-sizing behavior when trying to do something else, annoyance caused by positioning and display changes, etc. This solution is good for SEO, is scalable, and has no other tangible effect when trying to do other things with your elements.

like image 1
dudewad Avatar answered Nov 10 '22 12:11

dudewad