[html] Why does this CSS margin-top style not work?

I try to add margin values on a div inside another div. All works fine except the top value, it seems to be ignored. But why?

What I expected:
What I expected with margin:50px 50px 50px 50px;

What I get:
What I get with margin:50px 50px 50px 50px;

Code:

_x000D_
_x000D_
#outer {_x000D_
     width: 500px; _x000D_
     height: 200px; _x000D_
     background: #FFCCCC;_x000D_
     margin: 50px auto 0 auto;_x000D_
     display: block;_x000D_
}_x000D_
#inner {_x000D_
     background: #FFCC33;_x000D_
     margin: 50px 50px 50px 50px;_x000D_
     padding: 10px;_x000D_
     display: block;_x000D_
}
_x000D_
<div id="outer">_x000D_
  <div id="inner">_x000D_
   Hello world!_x000D_
  </div>_x000D_
</div>
_x000D_
_x000D_
_x000D_

W3Schools have no explanation to why margin behave this way.

This question is related to html margin css

The answer is


Not sure why what you have doesn't work, but you can add

overflow: auto;

to the outer div.


try this:

#outer {
    width:500px; 
    height:200px; 
    background:#FFCCCC;
    margin:50px auto 0 auto;
    display:table;
}
#inner {
    background:#FFCC33;
    margin:50px 50px 50px 50px;
    padding:10px;
    display:block;
}?

http://jsfiddle.net/7AXTf/

Good luck


Use padding-top:50pxfor outer div. Something like this:

#outer {
    width:500px; 
    height:200px; 
    background:#FFCCCC;
    margin:50px auto 0 auto;
    display:table;}

Note: padding will increase the size of your div. In this case if the size of your div is important, I mean if it must have a specific height. decrease the height by 50px.:

#outer {
    width:500px; 
    height:150px; 
    background:#FFCCCC;
    margin:50px auto 0 auto;
    display:table;}

Just for a quick fix, try wrapping your child elements into a div element like this -

<div id="outer">
   <div class="divadjust" style="padding-top: 1px">
      <div id="inner">
         Hello world!
      </div>
   </div>
</div>

Margin of inner div won't collapse due to the padding of 1px in-between outer and inner div. So logically you will have 1px extra space along with existing margin of inner div.


Create new block formatting context

You can use display: flow-root on the parent element to prevent margin collapsing through the containing element as it creates new Block Formatting Context.

Changing the value of the overflow property to auto or using flexbox will have the same effect.

https://codepen.io/rachelandrew/pen/VJXjEp


Have you tried !important before all, it will force everything:

margin:50px 50px 50px 50px !important;

I guess setting the position property of the #inner div to relative may also help achieve the effect. But anyways I tried the original code pasted in the Question on IE9 and latest Google Chrome and they already give the desirable effect without any modifications.


Doesn't answer the "why" (has to be something w/ collapsing margin), but seems like the easiest/most logical way to do what you're trying to do would be to just add padding-top to the outer div:

http://jsfiddle.net/hpU5d/1/

Minor note - it shouldn't be necessary to set a div to display:block; unless there's something else in your code telling it not to be block.


If you add any padding to #outer, it works.

Demo

#outer {
    width:500px; 
    height:200px; 
    background:#FFCCCC;
    margin:50px auto 0 auto;
    display:block;
    padding-top:1px;
}

What @BoltClock mentioned are pretty solid. And Here I just want to add several more solutions for this problem. check this w3c_collapsing margin. The green parts are the potential thought how this problem can be solved.

Solution 1

Margins between a floated box and any other box do not collapse (not even between a float and its in-flow children).

that means I can add float:left to either #outer or #inner demo1.

also notice that float would invalidate the auto in margin.

Solution 2

Margins of elements that establish new block formatting contexts (such as floats and elements with 'overflow' other than 'visible') do not collapse with their in-flow children.

other than visible, let's put overflow: hidden into #outer. And this way seems pretty simple and decent. I like it.

#outer{
    width: 500px;
    height: 200px;
    background: #FFCCCC;
    margin: 50px auto;
    overflow: hidden;
}
#inner {
    background: #FFCC33;
    height: 50px;
    margin: 50px;
}

Solution 3

Margins of absolutely positioned boxes do not collapse (not even with their in-flow children).

#outer{
    width: 500px;
    height: 200px;
    background: #FFCCCC;
    margin: 50px auto;
    position: absolute; 
}
#inner{
    background: #FFCC33;
    height: 50px;
    margin: 50px;
}

or

#outer{
    width: 500px;
    height: 200px;
    background: #FFCCCC;
    margin: 50px auto;
    position: relative; 
}
#inner {
    background: #FFCC33;
    height: 50px;
    margin: 50px;
    position: absolute;
}

these two methods will break the normal flow of div

Solution 4

Margins of inline-block boxes do not collapse (not even with their in-flow children).

is the same as @enderskill

Solution 5

The bottom margin of an in-flow block-level element always collapses with the top margin of its next in-flow block-level sibling, unless that sibling has clearance.

This has not much work to do with the question since it is the collapsing margin between siblings. it generally means if a top-box has margin-bottom: 30px and a sibling-box has margin-top: 10px. The total margin between them is 30px instead of 40px.

Solution 6

The top margin of an in-flow block element collapses with its first in-flow block-level child's top margin if the element has no top border, no top padding, and the child has no clearance.

This is very interesting and I can just add one top border line

#outer{
    width: 500px;
    height: 200px;
    background: #FFCCCC;
    margin: 50px auto;
    border-top: 1px solid red;

}
#inner {
    background: #FFCC33;
    height: 50px;
    margin: 50px;

}

And Also <div> is block-level in default, so you don't have to declare it on purpose. Sorry for not being able to post more than 2 links and images due to my novice reputation. At least you know where the problem comes from next time you see something similar.


Try using display: inline-block; on the inner div.

#outer {
    width:500px; 
    height:200px; 
    background:#FFCCCC;
    margin:50px auto 0 auto;
    display:block;
}
#inner {
    background:#FFCC33;
    margin:50px 50px 50px 50px;
    padding:10px;
    display:inline-block;
}

Not exactly sure why, but changing the inner CSS to

display: inline-block;

seems to work.


Examples related to html

Embed ruby within URL : Middleman Blog Please help me convert this script to a simple image slider Generating a list of pages (not posts) without the index file Why there is this "clear" class before footer? Is it possible to change the content HTML5 alert messages? Getting all files in directory with ajax DevTools failed to load SourceMap: Could not load content for chrome-extension How to set width of mat-table column in angular? How to open a link in new tab using angular? ERROR Error: Uncaught (in promise), Cannot match any routes. URL Segment

Examples related to margin

Can we define min-margin and max-margin, max-padding and min-padding in css? Does bootstrap have builtin padding and margin classes? Removing body margin in CSS How do I force a vertical scrollbar to appear? How to adjust gutter in Bootstrap 3 grid system? How to disable margin-collapsing? Why is there an unexplainable gap between these inline-block div elements? Remove "whitespace" between div element Remove all padding and margin table HTML and CSS Using margin / padding to space <span> from the rest of the <p>

Examples related to css

need to add a class to an element Using Lato fonts in my css (@font-face) Please help me convert this script to a simple image slider Why there is this "clear" class before footer? How to set width of mat-table column in angular? Center content vertically on Vuetify bootstrap 4 file input doesn't show the file name Bootstrap 4: responsive sidebar menu to top navbar Stylesheet not loaded because of MIME-type Force flex item to span full row width