如何将具有较低z-index的元素的子元素放在具有较高z-index的另一个元素的子元素前面?

5

我有以下设置:

<div style="z-index: 10">
      <div>Whatever</div>
</div>

<div style="z-index: 9">
      <div><div>Haaaleluia</div></div>
</div>

当然......我过于简化了设置,但这是主要思想。 "whatever" div被"Haaaaleluia" div覆盖。当然,因为第一个父级具有更大的z-index,“whatever”可见,而“haaaleluia”不可见。
在不改变设置的情况下(并且保持父级z-indexes),如何使“Haaaaleluia”处于顶部?
对于那些要求打印的人,在此提供...也感谢您的帮助: “enter 大地图是第二个div。
教程是第一个div。
订单面板是地图的子项。我需要它置于顶层。如果我将整个地图置于顶层,则教程将不再可见。如果我将地图保留在订单面板之后,则订单面板将不再可见。

让我们对js说“是”吧...但不能将子元素移动到父元素之外。就像我所说...设置是固定的。 - zozo
你为什么想让那个div在顶部,但不改变元素的样式? - Christoph
1
我从来没有理解过像“你为什么要这样做?”这样的问题,尤其是当问题与脚本或其他可能有其他答案的东西无关时。答案总是相同的:“我有一个项目,我已经在这个项目上工作了6个月,我遇到了这种情况,我不想再花4-5个小时重新制作整个布局,只是因为一个该死的z-index。” - zozo
多写一点代码会非常有帮助。我们可以将其加载到JSFiddle中,以查看您正在使用的样式约束,并找到解决方法。 - Phil
5个回答

8
简而言之,你做不到。父元素的子元素的z-index值不能低于兄弟元素,并且给该子元素赋予比父元素的兄弟元素更高的z-index值也是不可能的,因为继承的z-index值是相对于父元素的(参见这个问题)。但是,根据您的设置,您可以完全删除z-index,让浏览器将您的顶部div放在下面的div上面。然后,您可以尝试给子元素赋予z-index值。Josh Comeau撰写了一篇深入探讨问题及各种解决方案/解决方法的优秀文章

我其实也有同样的想法,所以+1(如果这是第一个相关的答案,我会给你+2 :))。问题在于第一个div必须在第二个div之上,而第二个div的子元素必须在第一个div之上(它是一个在鼠标悬停在某些元素上时打开的面板)。如果我让浏览器默认播放,整个第二个div将覆盖第一个div。解决方案是改变它们的顺序,但那将完全破坏定位(这就是我问这个问题的主要原因...需要花费几个小时来重新制作,而且由于所有内容都是为了一个该死的z-index...)。 - zozo
1
谢谢。在这种情况下...我认为你运气不好。唯一(混乱)实现它的方法是更改标记,使那些div不再是子元素。或者,根据您想要实现的内容,也许可以使用生成的内容或JavaScript:我认为没有纯CSS解决方案。 - CherryFlavourPez

2
不改变位置、z-index或重新排列任何元素,我想到的唯一让下面的div显示的方法是更改覆盖它的div的visibility、display或opacity。也就是说,在“Whatever”的父div上使用以下CSS样式之一:
visibility: hidden;
display: none;
opacity: 0;

你基本上是要求在一个具有更高 z-index 的元素之上显示另一个元素,这违背了使用 z-index 的目的。如果你想控制元素重叠的方式,应该使用 z-index。我建议您重新考虑如何组织您的元素(也许将 "Haaaleluia" div 移到其父级之外,并为其分配自己的 z-index)。否则,我建议您考虑创建 "Haaaleluia" 的副本以显示在 "Whatever" 之上,这可能适合您的情况,也可能不适合。
编辑:查看您提供的图像,将订单框的父级更改为教程 div 的父级可能适合您。这里有一个使用 jQuery 的 demo 可能会帮助说明这一点 - 只需将 hover 事件更改为启动教程的事件即可。另一种选择可能是克隆订单框并将其放置在下面的订单框之上,但具有更高的 z-index(以便用户只看到一个,但克隆品重叠在其他所有内容上)。这假定您的地图 div 是绝对或相对定位的。希望这可以帮到你。

想象一下,上面的 div 比后面的 div 更小。现在想象一下,在这种设置中,它们两个都可见。听起来好像去除可见性可以解决问题吗? - zozo
1
@zozo,我只是根据你在问题和评论中提供的信息,给出了一些可能的选项的建议。我给出了选项,解释了为什么我认为你的确切请求可能不起作用,并提出了替代方案。如果你认为答案太笼统,不适合你的具体情况,请提供更多细节。正如你在问题中所说,你提供的示例是“过于简化”的。我只能利用你给我的东西来工作。 - Zhihao
好的好的...取消了踩。还加了打印语句。(编辑回答,这样我就可以删除它了)。 - zozo
@zozo 谢谢,我已经更新了我的答案,也许可以解决你添加的图片问题。只是想帮忙。 :) - Zhihao
我知道,谢谢你的尝试。很抱歉让你烦恼了……我今天心情不好。 - zozo

2

设计不错。

好的,首先我要说的是,我相信解决你的分层问题的方法,就像其他人已经建议的那样,是将该框移出其父级(地图)。

但是你设置了一些限制,所以我会尽量少破坏它们。我不知道如何在不违反任何限制的情况下完成此操作。Z-index是继承的(同样,其他人已经指出了这一点),因此您无法仅使用该工具突破父级的层。

因此,以下是一种使用JavaScript实现相同效果的方法。它很丑陋,可能会在以后给你带来更多麻烦,但至少应该可以工作:

  1. 找到要置于顶部的div的绝对位置。
  2. 复制它。
  3. 隐藏原始元素(如果它是不透明的,则可选)。
  4. 将副本插入到所有内容的顶部。

如果您正在使用jQuery,则可以使用.offset()函数获取元素相对于文档的位置。之后就很简单了:

$(document).ready( function() {

    $("a[href='#overlay']").click( function() {
        // 1: get the position
        pos = $('.wrap').offset();
        // 2: make a copy
        halecopy = $('.bottom .wrap').clone();
        // 3: hide the original
        $('.bottom .wrap').css({opacity: 0});
        // 4: Insert new label on top of everything
        $('body').prepend(halecopy);
        // position the new label correctly
        halecopy.css({position:'absolute',
                      top: pos.top,
                      left: pos.left,
                      'z-index': 2});
        // show the "top" layer
        $('.top').fadeIn();
    });

    $("a[href='#hide']").click( function() {
        $('.top').fadeOut( function() {
            // remove the label copy
            halecopy.remove();
            // show the original again
            $('.bottom .wrap').css({opacity: 1});
        });
    });

});​

这个脚本在我的标记上运行良好:

<div class="top">
    <div class="label">
        <p>Whatever</p>
    </div>
</div>

<div class="bottom">
    <div class="wrap">
        <div class="label">
            <p>Haaaleluuuuia!</p>
        </div>
    </div>
</div>

<a href="#overlay">show</a>
<a href="#hide">hide</a>​

有了这些样式:

.top,
.bottom {
    position: absolute;
    top: 10%;
    left: 3%;
}

.top {
    z-index: 1;
    padding: 2%;
    background: rgba(0, 127, 127, 0.8);
    display:none;
}

.bottom {
    z-index: -1;
    padding: 3%;
    background: rgba(127, 127, 0, 0.8);
}

.label {
    color: #fff;
}

.wrap {
    outline: 1px dashed rgba(127, 0, 0, 0.8);
    background: rgba(127, 127, 127, 0.8);
}

.bottom .label {
    z-index: 10;
}
​

这里有一个方便的jsfiddle演示


+1鼓励一下你的努力...看起来不可能在不违反任何约束条件的情况下完成,所以我可能会围绕你的答案做一些调整。 - zozo

0

这只是一个可能有效的想法。

  1. 使用 jquery 获取 z-index = 9 的 div。
  2. 然后选择具有 z-index 为 9 的 div 的第一个子级的第一个子级。
  3. 然后应用以下样式:

$(获得的元素).attr("style", "position: absolute; z-index: 12;")

该样式将应用于该小元素,并且它将在红色框中可见。


2
由于其父级比其他父级具有较低的z-index,因此该元素仍将位于下方。 父级z-index优先于子级。 - zozo

0

添加颜色到div以演示层叠:

<div style="position:absolute;background:blue;z-index: 10">
      <div>Whatever</div>
</div>

<div style="position:absolute;background:red;z-index: 11">
      <div><div>Haaaleluia</div></div>
</div>

就像我之前说的那样...我过于简化了。你可以看到,我没有指定尺寸、颜色或任何其他细节。只是我不知道...想象一下一个绿色的正方形放在一个更大的红色正方形上面(“whatever”是大的那个,我需要小的那个在上面)。另外,我只是说父元素的z-index是固定的。 - zozo

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