z-index与绝对定位不起作用

181

我打开了控制台(chrome\firefox),并运行了以下代码:

$("body").append("<div id=\"popupFrame\" style=\"width:100%;height:100%;background-color:black;opacity:0.5;position:absolute;top:0;left:0;z-index:1;\" />");
$("body").append("<div id=\"popupContent\" style=\"width:200px;height:200px;z-index:1000;background-color:white;\" >dasdasdsadasdasdasdasdasd</div>");

#popupContent 应该在最上面,但受 #popupFrame 的不透明度影响。

这个内容不包含在 #popupFrame 中,这让事情变得非常奇怪。

目标是创建一个类似于 Firefox 弹出框的效果。

8个回答

315

第二个div的位置是static(默认值),因此z-index不适用于它。

如果您想要设置z-index属性,则需要将要设置该属性的元素进行定位(将position属性设置为除static以外的任何其他值,对于此示例,您可能希望使用relative)。


93

虽然这是一个旧问题,但这个答案可能会对某些人有帮助。

如果您尝试在容器的边界之外显示容器的内容,请确保它没有overflow:hidden,否则超出它的任何内容都将被截断。


62

透明度会改变z-index的上下文,而静态定位也会如此。要么给没有透明度的元素添加透明度,要么从具有透明度的元素中删除它。您还需要将两个元素都设置为静态定位,或者指定相对或绝对定位。这里有关于上下文的一些背景信息:http://philipwalton.com/articles/what-no-one-told-you-about-z-index/


4
哇。根据这篇文章,这包括不透明度、"transform"、滤镜、CSS区域、页面媒体,以及可能包括其他功能。 - jchook
2
哇,不知道这个!真的很有帮助。谢谢。 - BaptisteGillard

50

z-index 只适用于已经被明确定位的元素。在 #popupContent 中添加 position: relative,你就可以顺利地进行下一步操作了。


9
我在使用 position: absolute; 时经常会遇到这个问题,我可以通过在子元素中使用 position: relative 来解决这个问题。 不需要将 position: absolute 更改为 relative,只需在子元素中添加即可。请查看下面两个示例:

let toggle = document.getElementById('toggle')

toggle.addEventListener("click", () => {
 toggle.classList.toggle('change');
})
.container {
  width: 60px;
  height: 22px;
  background: #333;
  border-radius: 20px;
  position: relative;
  cursor: pointer;

}

.change .slide {
  transform: translateX(33px);
}

.slide {
  transition: 0.5s;
  width: 20px;
  height: 20px;
  background: #fff;
  border-radius: 20px;
  margin: 2px 2px;
  z-index: 100;
}

.dot {
  width: 10px;
  height: 16px;
  background: red;
  position: absolute;
  top: 4px;
  right: 5px;
  z-index: 1;
}
<div class="container" id="toggle">
  <div class="slide"></div>
  <div class="dot"></div>
</div>

使用相对定位(position relative)修复的方法如下:

let toggle = document.getElementById('toggle')

toggle.addEventListener("click", () => {
 toggle.classList.toggle('change');
})
.container {
  width: 60px;
  height: 22px;
  background: #333;
  border-radius: 20px;
  position: relative;
  cursor: pointer;

}

.change .slide {
  transform: translateX(33px);
}

.slide {
  transition: 0.5s;
  width: 20px;
  height: 20px;
  background: #fff;
  border-radius: 20px;
  margin: 2px 2px;
  z-index: 100;
  
  // Just add position relative;
  position: relative;
}

.dot {
  width: 10px;
  height: 16px;
  background: red;
  position: absolute;
  top: 4px;
  right: 5px;
  z-index: 1;
}
<div class="container" id="toggle">
  <div class="slide"></div>
  <div class="dot"></div>
</div>

这里是沙盒


3
如果你像我一样是个傻瓜(但知道定位规则完全正确),想要得到这样的效果:
将此 undesired result 变成这样的:
将此 enter image description here 你的解决方案可能就是确保你想置于其他元素前/后的元素背景是透明的。

1
可能已经有点晚了,但它可以作为一种替代方法。绝对定位元素的层叠顺序取决于将元素插入父元素的顺序。换句话说,可以通过使用$(parent).prepend(me)将其发送到后面,而通过使用$(parent).append(me)将其带到前面,而不是使用z-index。

function BringToFront(){
  $("#parent").append($("#me"));
}

function SendToBack(){
  $("#parent").prepend($("#me"));
}
#mySister{
  position:absolute;
  left:25px;
  top:25px;
  width:100px;
  height:100px;
  background-color: red;
}

#me{
  position:absolute;
  left:50px;
  top:50px;
  width:100px;
  height:100px;
  background-color: yellow;
}

#myBrother{
  position:absolute;
  left:75px;
  top:75px;
  width:100px;
  height:100px;
  background-color: blue;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div id="parent">

  <div id="mySister">&nbsp;</div>

  <div id="me">Hello! this is me!</div>
  
  <div id="myBrother">&nbsp;</div>

</div>

<button type="button" onclick="BringToFront()">Bring to front</button>
<button type="button" onclick="SendToBack()">Send to back</button>


0

我曾经遇到过同样的问题,尝试通过在一个带有 sticky positiondiv 中使用 absolute positionappend 元素来解决它。我的问题出现在速拨 (reactjs + material) 中,所以我不知道它是否适用于所有情况。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接