baltusaj baltusaj - 9 months ago 34
CSS Question

Why is setting position:absolute working unexpectedly?

I have a parent and a child div. Parent has one image. Child div has another image. Child image needs to appear in top-left corner of parent image for which I thought to set position of child image to

absolute
and parent's position to some non-static position, say
relative
or
absolute
. (I set
left
and
top
too but let's forget about it for now.)

This is because setting
absolute
for the child should work only if its first ancestor is positioned non-statically as according to W3Schools
absolute
means The element is positioned relative to its first positioned (not static) ancestor element.

But I noticed that even if I don't set position of the parent (i.e. its position will be "static" by default), event then the child image still gets positioned nicely in top-left.

Can someone help me understand why I don't have to set position of the parent to some non-static value in order for the
absolute
property to work properly? or did I understand working of
absolute
incorrectly?

<div class="parent">
<img src="https://lh4.ggpht.com/wKrDLLmmxjfRG2-E-k5L5BUuHWpCOe4lWRF7oVs1Gzdn5e5yvr8fj-ORTlBF43U47yI=w300">
<div class="child">
<img src="http://xiostorage.com/wp-content/uploads/2015/10/test.png" width="200">
</div>
</div>

/*.parent {
position:relative;
}*/

.child {
display:none;
position:absolute;
left:0;
}
.parent:hover .child {
display:initial;
}


Here is the JSFiddle code.

Answer Source

Two general rules to keep in mind:

  • An absolutely positioned element will be positioned within its containing block, which is defined by the nearest positioned ancestor. However, if there is no positioned ancestor, the containing block is the initial containing block (i.e., the viewport).

    Your .parent div is pretty much aligned at the top-left corner of the viewport. That's why your absolutely positioned child will have similar positioning in either containing block.

  • When you apply position: absolute to an element you remove it from the normal flow. That's it. The element will still be positioned as though it were in the normal flow. It isn't until you apply the CSS offset properties (left, right, top, bottom) that you actually position the element.