0

I have sibling divs in a page, let's call them parents. And these parents have one child divs each. You can think of these child divs as custom tooltips. By default, child divs are hidden. When I hover one of the parents, it's child div becomes visible.

Because of painting order, when I hover first parent, it's child becomes visible below second parent which painted last on the page. All parents have the same z-index which is 1, as well as all child divs have the same z-index which is 2.

All child divs needs to be drawn on top. How can I override it to work like this?

You can find my problem as reproducible below:

.parent{
    position: relative; height: 200px; width: 200px; z-index: 1; display: inline-block;
}
.parent:hover .child{
    display: block;
}
.child{
    position: absolute; height: 50px; width: 50px; z-index: 2; display: none;
}
 <div class="parent" style="background-color: hotpink;">Parent 1<div class="child" style="background-color: yellow; margin-left: 180px; margin-top: 50px;">Child 1.1</div></div>
 <div class="parent" style="background-color: green;">Parent 2<div class="child" style="background-color: greenyellow; margin-left: -30px;">Child 2.1</div></div>
YSFKBDY
  • 735
  • 1
  • 12
  • 38
  • You change from position absolute to block. This is strange. I would suggest to use a different prop. It could be scale which can be animated unlike the display prop for example. – The Fool Dec 25 '20 at 07:21

2 Answers2

3

The main reason why this behaviour is happening is because:

The child element in Parent1 is in lower stacking order than the Parent Element 2.

Even though it may appear in the first look that first child in first Parent has z-index of 2, but this is with respect to the ParentElement1 not ParentElement2.

Let me give a demo example:

.content { 
   position: relative; 
   z-index: 1; 
   background:orange;
   height:400px;
   width:400px;
} 

.child { 
   position: absolute; 
   z-index: 100; 
   background:green;
   height:200px;
   width:200px;
   bottom:0;
   left:0;
} 

.side-tab { 
   position: absolute; 
   z-index: 5; 
   background:teal;
   height:300px;
   width:300px;
   top:10px;
}
<section class="content">            
    <div class="child"></div>
</section>

<div class="side-tab"></div>

Looking at the markup, we can see that the content and side tab elements are siblings. That is, they exist at the same level in the markup (this is different from z-index level). And the child div is a child element of the content element.

Because the child is inside the content element, its z-index of 100 only has an effect inside its parent, the content element.

But the z-index value of child element doesn't mean anything outside the parent, because the parent content element has its z-index set to 1.

So its children, including the child, can’t break out of that z-index level.

SOLUTION: There are two solutions to this problem.

  1. Remove positioning from the content, so it won’t limit the child's z-index.

So in your example if your remove position:relative from the Parent this will solve the issue.

.parent{
    position: static; height: 200px; width: 200px; display: inline-block; // Removed position:relative from here
}

Since the parent element is now unpositioned, it will no longer limit the child's z-index value.

  1. Move the child outside of the parent, and into the main stacking context of the page. (But this would mess things up for you because then you will need to change your markup)

Hope this covers the positioning issue's that we face with z-index.

Imran Rafiq Rather
  • 7,677
  • 1
  • 16
  • 35
1

remove .parent's z-index: 1

.parent{
    position: relative; height: 200px; width: 200px; display: inline-block;
}
.parent:hover .child{
    display: block;
}
.child{
    position: absolute; height: 50px; width: 50px; z-index: 2; display: none;
}
 <div class="parent" style="background-color: hotpink;">Parent 1<div class="child" style="background-color: yellow; margin-left: 180px; margin-top: 50px;">Child 1.1</div></div>
 <div class="parent" style="background-color: green;">Parent 2<div class="child" style="background-color: greenyellow; margin-left: -30px;">Child 2.1</div></div>
Alien
  • 3,658
  • 1
  • 16
  • 33