So I asked this question: google chrome issue with fixed position and margin-top which finally got me to realize that top
and margin-top
are not the same thing. I don't know how I've missed that all these years.
Anyways that got me thinking what is the difference exactly between margin-top
and top
, which is how I found this question: CSS: Top vs Margin-top.
I already knew what margin-top
did. But I had never extrapolated that out to think "hmm, this element is not in the DOM flow so what exactly is margin-top
pushing it away from?"
From the question I asked I know that margin-top
behaves in very unexpected ways when applied to an element with a fixed
position. And that in Chrome at least this can lead to some crazy rules (like margin-top: -273%;
).
So my Question is: How do browsers apply margin
rules to elements not in the DOM flow (i.e. elements with a position
value of fixed
or absolute
. And what about the way they are applied and rendered leads to rules, like the one described above, actually rendering the element inside the view-port?
The top
property simply determines how far from the top of the containing element that the box-model should start being rendered. In the case of position: fixed
, that is the window itself. In the case of position: absolute
, it is the next parent element with a non-static position.
Margin, on the other hand, is part of the box-model itself. Adding margin to the top of the box increases the empty space present above the box.
Consider the following layers for a position: fixed
box:
top:10px
margin-top:10px
------------border-top:1px------------
padding-top:10px
content
All of the margin, border, and padding are part of the box model. That entire element, or "piece", is just one big square when positioning. So, if you have a margin of 10px on the top of the box, and position the element 10px from the top, it will have the appearance of having 20px of margin between the top of the window and where the visible box starts.
I've also made a very simple example in jsFiddle.
If you like graphics, take this example, where the red box has a position: fixed
:
As you can see in the first section, only setting position: fixed
on the element doesn't actually move it anywhere. It just removes it from the flow of the document.
In the section section, adding a margin-top: 10px
makes the element move down 10px because the box now has 10px of margin on the top of it. However, it hasn't actually moved anywhere. The box has just gotten taller because the box model has changed.
In the third section, using a top: 10px
actually moves the box to be 10px from the top of the window container. It has the exact same box model as in the first section.
Section four is like the second section above it, except the negative margin causes it to move up ten pixels. The box model is still taller and the box still hasn't moved.
When you set an absolute position on an element, the element doesn't move at all if you don't set any other position properties. So, without a top
, right
, bottom
, or left
property set, the element stays in the position it would have been in if it had been rendered as part of the flow, it's just now removed from the flow. So adding a margin, either positive or negative, makes it appear to move up or down from that position. In reality, you're just changing the element's box model though.
You also have to realize that using a percentage on top and bottom margins (and even paddings) has nothing to do with the height. It actually uses the width to figure out how much margin is there. Saying margin-top: 10%
will make that value 10% of the available width, not the available height, and making it negative will just negate that value. I mentioned this because it is relevant to that first question you linked where you were using percentages for margin-top
.
I hope this covered what you were looking for. I couldn't tell what exactly you were confused about so I just explained as much as I could.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With