CSS过渡和z-index

11

我有一个固定的顶部导航栏,并带有下拉菜单。我想要在悬停时滑动下拉菜单。我希望在滑入时菜单位于导航栏后方。因此,我尝试设置两个元素的 z-index,但不幸的是这对我没有起作用。

这里是一个简化的示例(codepen

html

<div class="fixed-top">
  <span class="trigger">hover me</span>
  <div class="menu"></div>
</div>

CSS

.fixed-top {
  background: #3b5999;
  height: 50px;
  width: 100%;
  padding: 0;
  top: 0;
  position: fixed;
  z-index: 2;
}

.trigger {
  z-index: 2;
  font-size: 33px;
  color: white;
  margin-left: 50%;
}

.trigger:hover + .menu {
  margin-top: 0;
}

.menu {
  z-index: 1;
  height: 300px;
  background-color: #1c7754;
  width: 400px;
  margin: auto;
  margin-top: -400px;
  transition: all 0.75s ease-out;
}

如果我的意图不够清晰,这里有一个简单的 MSPaint 草图 ;)

mspaint 技能已确认


@Justcode 我的选择器实际上运行良好 :D,你的代码结果与我的相同。 - boop
是的,但当我点击时它没有像现在这样工作 :P - Just code
1
这可能会帮助您更好地理解堆叠上下文:https://dev59.com/HFwY5IYBdhLWcg3wh4Pc#32515284 - Michael Benjamin
3个回答

10
这是在CSS中开始使用堆叠上下文时非常常见的错误。基本上,你只需要记住子元素不能存在于与父元素不同的堆叠上下文中。
因此,如果我有一个非静态元素(即具有position:anything-but-static [fixed,relative,absolute]的元素),并且该元素没有非静态父元素,则无论该元素在DOM中的位置如何,它都将处于堆叠上下文级别1。现在,如果该元素具有非静态子元素,则该子元素将位于堆叠上下文级别2。它不能与其父元素在同一级别(级别1)上。z-index只能影响在同一堆叠上下文级别上的元素,与不同堆叠上下文级别上的元素无关。 解决方案是重新构建你的HTML,或者只使用:before:after伪元素,如下所示:
.fixed-top {
    height: 50px;
    width: 100%;
    padding: 0;
    top: 0;
    position: fixed; /* The parent: stacking context level 1 */
}
.fixed-top:before {
    background: #3b5999;
    content:'';
    position: absolute; /* stacking context level 2 */
    top: 0; right: 0; bottom: 0; left: 0;
    z-index: 1;
}
.trigger {
    color: white;
    font-size: 33px;
    margin-left: 50%;
    position: relative; /* also stacking context level 2 */
    z-index: 2;
}
.trigger:hover + .menu {
    margin-top: 0;
}
.menu { /* bottom layer -- no stacking context necessary */
    z-index: 0;
    height: 300px;
    background-color: #1c7754;
    width: 400px;
    margin: auto;
    margin-top: -400px;
    transition: all 0.75s ease-out;
}

请注意注释,它们表示堆叠上下文层级。
这里有一个示例JSFiddle

不错,还需要将它更改为这样:.trigger:hover + .menu, .menu:hover,这样当鼠标离开 span 时菜单就不会滑回去了,+1。 - Mi-Creativity
@Mi-Creativity,我不能确定那是否是规格的一部分,但我会因你的建议而给予赞扬。 - bowheart
这就是我一直在寻找的答案。我现在看到了这些症状,经过一些z-index的调整后,我开始强烈感觉子元素永远不能在父元素下面。我还没有解决它,但在你的帖子和示例之间,我应该能够解决它。 - agm1984

4

尝试运行这段代码片段。

.fixed-top {
  background: #3b5999;
  height: 50px;
  width: 100%;
  padding: 0;
  top: 0;
  position: fixed;
  z-index: 2;
}

.trigger {
  font-size: 33px;
  color: white;
  margin-left: 50%;
  width: 100%;
  height: 50px;
  top: 0;
  position: fixed;  
  z-index: 3;  
}

.trigger:hover + .menu,
.menu:hover{
  margin-top: 0;
}

.menu {
  z-index: 1;
  height: 300px;
  background-color: #1c7754;
  width: 400px;
  margin: auto;
  margin-top: -400px;
  transition: all 0.75s ease-out;
}
<div class="fixed-top"></div>
<span class="trigger">hover me</span>
<div class="menu"></div>


这个可以用,谢谢。但说实话我不是很满意.. :D 相关问题 - boop
嗯,如果有人能在不破坏你的HTML骨架的情况下实现它,那么我会感到惊讶 :) - Aung Myo Linn
@kolunar 你的意思是像我在答案中所做的那样吗? - bowheart
@bowheart 啊!你做到了,伪元素的:before掩盖起来就行了 :D - Aung Myo Linn

0

我认为这就是你想要的。

CSS 代码

    .fixed-top {
  background: #3b5999;
  height: 50px;
  width: 100%;
  padding: 0;
  top: 0;
  position : fixed;
}

.trigger {
  z-index: 500;
  font-size: 33px;
  color: white;
  margin-left: 50%;
  position : absolute;
}

.trigger:hover + .menu {
  margin-top: 0;
}

.menu {
  z-index: -9999;
  position : relative;
  height: 300px;
  background-color: #1c7754;
  width: 400px;
  margin: auto;
  margin-top: -400px;
  transition: all 0.75s ease-out;
}

    <div class="fixed-top">
  <span class="trigger">hover me</span>
  <div class="menu"></div>
</div>

这是您可以查看的参考资料

http://www.smashingmagazine.com/2009/09/the-z-index-css-property-a-comprehensive-look/


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