简体   繁体   中英

Absolute position div don't overlays another's div child

<div class="wrapper">
  <div class="avatar"></div>
  <div class="desc an-all"></div>
</div>
<div class="wrapper">
  <div class="avatar"></div>
  <div class="desc an-all"></div>
</div>

.wrapper{
  position: relative;
  width: 250px;
  height: 150px;
  cursor: pointer;
}

.wrapper:hover .desc{
  opacity: 1;
}

.avatar{
  width: 70px;
  height: 70px;
  background: green;
  position: relative;
  z-index: 30;
}

.desc{
  position: absolute;
  top: 50px;
  left: 0;
  height: 250px;
  width: 100%;
  background: red;
  opacity: 0;
  z-index: 20;
}

.an-all{
-webkit-transition: all 0.3s linear;
-moz-transition: all 0.3s linear;
transition: all 0.3s linear;
}

I can't figure out why is this happening. I thought that a position element inside a parent with position relative only apply inside parent and outside is a different world.

Why when I hover the green box of the first wrapper div the red one don't overlay the second's wrapper div green box ? I want the red box to be under the green one when I hover

http://codepen.io/laxmana/pen/txKbF

See if you like this example: JSFiddle

It uses your same working code, but the wrapper divs are placed within a relative parent, and each are given their own z-index. This is how you can layer one on top of another. In a real world example, the divs may not be together (like a tooltip), and then you wouldn't need the additional parent. The parent is useful when the divs are together, and on the same level. Play around with the JSFiddle, and try different options with content.

In the original example, the reason the green divs were always on top, regardless of their html order, is because the red divs are absolutely positioned, and the 2 wrapper elements are on the same level within the parent.

.wrapper {
    position: relative;
    width: 250px;
    height: 150px;
    cursor: pointer;
}
.wrapper:hover .desc {
    opacity: 1;
}
.relative-container {
    position:relative;
}
.top {
    z-index:10;
}
.bottom {
    z-index:9;
}
.avatar {
    width: 70px;
    height: 70px;
    background: green;
    position: relative;
    z-index: 30;
}
.desc {
    position: absolute;
    top: 50px;
    left: 0;
    height: 250px;
    width: 100%;
    background: red;
    opacity: 0;
    z-index: 20;
}
.an-all {
    -webkit-transition: all 0.3s linear;
    -moz-transition: all 0.3s linear;
    transition: all 0.3s linear;
}

Update

Here is an example with multiple display:inline-block divs. The trick is for the z-index to work, the divs need to be siblings/on the same level as each other (this works for other elements too). The first div in the row that needs to go on top gets the highest z-index, while the last div gets the lowest z-index.

JSFiddle Example

Here is a great resource explaining the details on the z-index https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Understanding_z_index/The_stacking_context

Note: In the second JSFiddle I used display:none on the red ".desc" dropdowns, and made them visible only when moused over by adding display:block; to ".wrapper:hover .desc". In your original code even though you don't see the red divs, when you hover over their invisible area it triggers them to show. By using display:none, they are truly not displayed in the page and therefore can't trigger the hover state. The trick is that display:block overwrites the display:none in the hover class, so they will show when the green buttons are hovered over.

This hides the red divs:

.desc {
    display:none;

This shows the red divs only when the green divs are hovered over:

.wrapper:hover .desc {
    display:block;

Your z-index needs to change. Right now, both red boxes have an index lower than the green, which is why it appears beneath the second green box.

Update Based on your comment, you want to have the green box both underlay the avatar class and overlay the same class below the wrapper . Because you're using classes alone, you can't have both actions. You could space the wrappers differently so you have the description still underlay the avatar and not overlap lower elements.

CSS

.wrapper{
  position: relative;
  width: 250px;
  height: auto;     /* Set this to auto to keep elements separate from one another */
  cursor: pointer;
}

.wrapper:hover .desc {
  opacity: 1;
}

.avatar{
  width: 70px;
  height: 70px;
  background: green;
  position: relative;
  z-index: 30;
}

.desc{
  position: relative; /* Keep it inside the document flow */
  top:-20px;          /* sets the overlap from the avatar class */
  left: 0;
  height: 250px;
  width: 100%;
  background: red;
  opacity: 0;
  z-index: 20;        /* Displays below the avatar */
}

.an-all{
-webkit-transition: all 0.3s linear;
-moz-transition: all 0.3s linear;
transition: all 0.3s linear;
}

Working pen

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM