Steve
Steve

Reputation: 4898

Why does margin-top affect the placement of an absolute div?

I have two divs in this jsFiddle - http://jsfiddle.net/z4062jfn/ - with absolute positioning. I didn't expect any margin values given to the divs to affect their absolute position. And this is true for a margin-bottom value given to the top div (uncomment line 8 of CSS). But a margin-top value given to the bottom box (uncomment line 19 of CSS) does move the bottom div position down by that amount.

What is there in this situation that lets a margin rule override an absolute position rule - sometimes?

<div id="box1"><p>box 1</p></div>
<div id="box2"><p>box 2</p></div>

Upvotes: 5

Views: 2793

Answers (4)

BoltClock
BoltClock

Reputation: 723568

The simple factual explanation for why this happens is that the offset properties top, right, bottom and left actually respect the corresponding margin properties on each side. The spec says that these properties specify how far the margin edge of a box is offset from that particular side. The margin edge is defined in section 8.1.

So, when you set a top offset, the top margin is taken into account, and when you set a left offset, the left margin is taken into account.

If you had set the bottom offset instead of the top, you'll see that the bottom margin takes effect. If you then try to set a top margin, the top margin will no longer have any effect.

If you set both the top and bottom offsets, and both top and bottom margins, and a height, then the values become over-constrained and the bottom offset has no effect (and in turn neither does the bottom margin).

If you're looking to understand why the spec defines offsets this way, rather than why browsers behave this way, then it's primarily opinion-based, because all you'll get is conjecture. That said, Fabio's explanation is quite reasonable.

Upvotes: 7

Devin
Devin

Reputation: 7720

Because an absolutely positioned box is removed from the normal flow and is assigned a position with respect to the containing block. If you don't define a containing block, then it's body.

So, with that in mind, think of the containing block as a coordinates axis that starts at top left. If you give your element this properties:

    position: absolute;
    top:100px;
    left:100px;

just like you did, you will have leave an empty space above and left, thus, if you apply margin-top or margin-left, it will work, because your elements are capable to virtually go through every pixel of both axises up to that 100px top and 100px left position, and same applies for negative margins. However, since position:absolute removes the element from the flow and any impact on any subsequent sibling element, it's easy to see that nothing can happen after the element "finishes", hence margin-bottom and margin-right won't work since they don't have anything to get margin from.

I have made an image to show the behavior since my explanation might be a bit obscure

enter image description here

Upvotes: 2

Savrige
Savrige

Reputation: 3755

Margin-bottom affect too. See the code below, if you set a bottom reference in #box1 it will apply 20px in margin-bottom.

http://jsfiddle.net/t5ooot7u/

#box1 {
    width:200px;
    height: 100px;
    background-color:gold;
    position: absolute;
    bottom:230px;
    left:100px;
    margin-bottom:20px;

}

Upvotes: 0

Leto
Leto

Reputation: 503

Your margin bottom is not working since you put the top property in your divs. Remove top and your margin bottom will work for your #box1.

Upvotes: 0

Related Questions