Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using position:absolute, the nearest positioned ancestor is having no effect

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.

Update: Connexo helped with following updated code.

Try uncommenting the position for parent to unlock the mystery. Accepted answer has more information.

<h1>
   Positioning test
</h1>
<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>

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

.child {
  display: none;
  position: absolute;
  left: 0;
  top: 0;
}
.parent:hover .child {
  display:initial;
}
like image 783
Usman Avatar asked Mar 11 '17 22:03

Usman


People also ask

What position element uses the document body if it has no position ancestors?

An element with position: absolute; is positioned relative to the nearest positioned ancestor (instead of positioned relative to the viewport, like fixed). However; if an absolute positioned element has no positioned ancestors, it uses the document body, and moves along with page scrolling.

Which of the CSS position is positioned relative to the nearest positioned ancestor?

Absolute positioning The absolutely positioned element is positioned relative to its nearest positioned ancestor (i.e., the nearest ancestor that is not static ).

Why you shouldn't use position absolute?

IF you were to use all absolute div tags you could easily have your tags overlap and hide each other when the data within them changed. Secondly, many good sites allow for the information to wrap depending on the screen resolution and browser size that a user uses to access the web page.

What happens when an element is positioned absolutely?

Absolutely positioned elements are removed entirely from the document flow. That means they have no effect at all on their parent element or on the elements that occur after them in the source code. An absolutely positioned element will therefore overlap other content unless you take action to prevent it.


2 Answers

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.

like image 175
Michael Benjamin Avatar answered Dec 21 '22 02:12

Michael Benjamin


You forgot setting top in your JSFiddle so all it did was get aligned to the left side of the page, where your image was as well. As soon as you add top: 0px in your JSFiddle you will notice that the image does end up in the top left corner of the page.

Below a simple demo with top added and a margin pushing the .parent away from the corner.

.parent {
  margin: 30px;
  /* position: relative;*/
}
.child {
  display:none;
  position:absolute;
  left:0;
  top:0;
}
.parent:hover .child {
  display:initial;
}
<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>
like image 27
David Mulder Avatar answered Dec 21 '22 03:12

David Mulder