Why does setting the margin on a div not affect the position of child content?
I'd like to understand a little more clearly how css margins work with divs and child content.
If I try this...
<div style="clear: both; margin-top: 2em;">
<input type="submit" value="Save" />
</div>
...the Save button is right up against the User Role (margin fail):
Margin Fail :( http://img697.imageshack.us/img697/8459/nomargin.jpg
If I change it to this...
<div style="clear: both;">
<input style="margin-top: 2em;" type="s开发者_开发问答ubmit" value="Save" />
</div>
...there is a gap between the Save button and the User Role (margin win):
Margin Win :) http://img20.imageshack.us/img20/1973/yesmargin.jpg
Questions:
Can someone explain what I'm observing? Why doesn't putting a margin on the div
cause the input
to move down? Why must I put the margin on the input
itself? There must be some fundamental law of css I am not grasping.
This would be because the the div
doesn't have an element to "push itself away from". It would seem that the select
that comes before the div
is floated. This causes it to be taken out of the normal page flow, and it doesn't act as reference for margin calculations anymore. The div
is clearing the float, i.e. it drops below it, then tests if there's a 2em margin to the next element above it that is within the same "flow". Apparently there is, so it doesn't move down any further.
Setting the margin on the submit
on the other hand is very clear cut, since the frame of reference for it is the parent div
.
Putting a margin on an element affects that element's margin only. Are you expecting it to be inherited or something? It isn't. Perhaps you're thinking of padding
? Try:
<div style="clear: both; padding-top: 2em;">
<input type="submit" value="Save" />
</div>
See Box Model:
Another thing to note about margins is that they merge. So:
<div>one</div>
<div>two</div>
with:
div { margin: 1em; }
will only result in a 1em gap between them not 2em. See 8.3.1 Collapsing Margins:
Vertical margins may collapse between certain boxes:
- Two or more adjoining vertical margins of block boxes in the normal flow collapse. The resulting margin width is the maximum of the adjoining margin widths. In the case of negative margins, the maximum of the absolute values of the negative adjoining margins is deducted from the maximum of the positive adjoining margins. If there are no positive margins, the absolute maximum of the negative adjoining margins is deducted from zero. Note. Adjoining boxes may be generated by elements that are not related as siblings or ancestors.
So one possible explanation for what you're seeing is that the element preceding your div already has a margin (at the bottom), which is why it's not being pushed down by adding a margin to your div.
Basically put borders around things and you should see what's happening.
What's happening in the first example is that the floating elements above the button is floating outside it's parent element.
The margin is working just fine, but it's not between the floating elements and tbe button, it's between the floating element's parent element and the button. The parent element doesn't have any non-floating elements, so it's height is zero, and the floating elements overlap the margin.
In your first example, you are setting a margin on the DIV itself. Think of the DIV as a block holding the nested elements. In this case, the nested element would be the button. If you do the following as you did:
<div style="clear: both; margin-top: 2em;">
<input type="submit" value="Save" />
</div>
You are not affecting the child elements style. Although the relative position of your button may change, your are not actually changing the style of the child element. Now by doing:
<div style="clear: both; margin-top: 2em;">
<input type="submit" value="Save" />
</div>
You are now setting the child elements margin. This will have a different result. Setting this child elements margin will not have an affect on the parent element (the DIV).
精彩评论