简体   繁体   English

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

[英]How can I get a child of an element with lower z-index on front of a child of another element with higher z-index?

I have the following setup:我有以下设置:

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

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

Of course... I oversimplified the setup but that's the main idea.当然......我过度简化了设置,但这是主要思想。 The "whatever" div is overlapped by the "Haaaaleluia" div. “whatever”div 与“Haaaaleluia”div 重叠。 Of course because the first parent has bigger z-index "whatever" is visible and "haaaleluia" is not.当然,因为第一个父母有更大的 z-index,“whatever”是可见的,而“haaaleluia”不是。

Without changing the setup (and to be clear that includes keeping the parents z-indexes), how can I make "Haaaaleluia" to be on top?在不更改设置的情况下(并且要明确包括保留父母的 z-indexes),我怎样才能让“Haaaaleluia”成为最重要的?

For those asked for print here it is... also thank you for help:对于那些在这里要求打印的人,它是......也感谢你的帮助:在此处输入图像描述

The big bad map is the second div.大坏地图是第二个 div。

The tutorial is the first div.教程是第一个div。

The panel with orders is child of the map.订单面板是地图的子面板。 I need it to be on top.我需要它在最上面。 If I set whole map on top, the tutorial is not visible any more.如果我将整个地图设置在顶部,教程将不再可见。 If I keep the map behind the orders panel is not visible any more.如果我将地图放在后面,订单面板将不再可见。

In short: you can't.简而言之:你不能。 It's not possible to have a child of a parent element with a z-index lower than a sibling, and give that child a higher z-index value than the parent's sibling, as the inherited z-index is relative to the parent (see this question for someone coming up against the same thing).不可能让父元素的子元素的z-index低于兄弟元素,并为该子元素赋予比父元素的兄弟元素更高的 z-index 值,因为继承的 z-index 是相对于父元素的(请参阅此对遇到同样事情的人提出的问题)。

However, depending on your setup, you can remove the z-indices completely, and let the browser place your top div above the one below.但是,根据您的设置,您可以完全删除 z 索引,并让浏览器将您的顶部div放在下面的 div 之上。 You could then play around with giving just the children a z-index value.然后您可以尝试只给孩子们一个z-index值。

Josh Comeau has a great article going into depth on the problem and various solutions/workarounds. Josh Comeau 有一篇很棒的文章深入探讨了这个问题和各种解决方案/变通方法。

Without changing the locations, z-index , or rearranging any of the elements, the only way I can think of that would allow the div underneath to appear would be to either change the visibility , display or opacity of the div overlapping the one you want to see.在不更改位置、 z-index或重新排列任何元素的情况下,我能想到的唯一允许下面的div出现的方法是更改与您想要的div重叠的visibilitydisplayopacity查看。

That is, use one of the following CSS styles on the parent div of "Whatever":也就是说,在“Whatever”的父div上使用以下 CSS 样式之一:

visibility: hidden;
display: none;
opacity: 0;

You're basically asking to display an element above another element that has a higher z-index , which defeats the purpose of having a z-index .您基本上是在要求将一个元素显示在另一个具有更高z-index的元素之上,这违背了拥有z-index的目的。 If you're trying to control how elements overlap, it really should be done with z-index .如果你想控制元素如何重叠,那真的应该用z-index来完成。 I would suggest you rethink how your elements are organized (maybe move the "Haaaleluia" div outside of its parent and assign it its own z-index ).我建议您重新考虑元素的组织方式(也许将“Haaaleluia” div移到其父级之外并为其分配自己的z-index )。 Otherwise, I might suggest you consider creating a duplicate of "Haaaleluia" to display above "Whatever", which may or may not suit your situation.否则,我可能会建议您考虑创建一个“Haaaleluia”的副本以显示在“Whatever”上方,这可能适合您的情况,也可能不适合您的情况。

Edit: Looking at the image you've provided, changing the parent of the order box to the parent of the tutorial div may work for you.编辑:查看您提供的图像,将订单框的父级更改为教程 div 的父级可能适合您。 Here is a demo using jQuery that may help illustrate the point - just change the hover event to whatever it is that starts the tutorial.这是一个使用 jQuery 的演示,可能有助于说明这一点 - 只需将悬停事件更改为启动教程的任何内容即可。 Another option may be to clone the order box to lay on top of the one below, but with a higher z-index (so that the user only sees one, but the clone overlaps everything else).另一种选择可能是将订单框复制到下方的顶部,但具有更高的z-index (以便用户只看到一个,但克隆与其他所有内容重叠)。 This is assuming that your map div is positioned either absolutely or relatively.这是假设您的地图 div 是绝对定位或相对定位的。 Hope that helps.希望有所帮助。

Nice design.漂亮的设计。

Ok so I'll first say that I believe the solution to your layering problem, as others have already suggested, is moving that box outside of its parent (the map).好的,所以我首先要说的是,正如其他人已经建议的那样,我相信您的分层问题的解决方案是将该框移出其父项(地图)。

But you set some constraints, so I'll try to break as few as possible.但是你设置了一些限制,所以我会尽量少打破。 I don't know how to do this without breaking any of your constraints.我不知道如何在不打破任何限制的情况下做到这一点。 Z-index is inherited (again, others have pointed this out), so you can't break out of your parents' layer with only that tool. Z-index 是继承的(同样,其他人已经指出了这一点),所以你不能只用那个工具来突破你父母的层。

So here's one way you could get the same effect, using javascript.因此,这是使用 javascript 可以获得相同效果的一种方法。 It's ugly, and might cause you more headaches later, but it should at least work:这很丑陋,以后可能会让你更头疼,但它至少应该有效:

  1. Find out the absolute position of the div that you want to put on top.找出要放在顶部的 div 的绝对位置。
  2. Make a copy of it.复制一份。
  3. Hide the original (optional if it's opaque).隐藏原件(如果不透明则可选)。
  4. Insert the copy on top of everything.将副本插入所有内容之上。

If you're using jQuery, you can get elements' position relative to the document with the .offset() function.如果您使用的是 jQuery,则可以使用.offset()函数获取元素相对于文档的位置。 After that it's fairly simple:之后就很简单了:

$(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});
        });
    });

});​

That script works for me on this markup:该脚本适用于此标记:

<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>​

With these styles:使用这些样式:

.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;
}
​

And here's a handly jsfiddle demo .这是一个方便的jsfiddle 演示

Added colour to the div's to demonstrate the layering:向 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>

This is just an idea which may work.这只是一个可行的想法。

  1. Get the div having z-index = 9 using jquery.使用 jquery 获取 z-index = 9 的 div。
  2. Then select the 1st child of 1st child of the div having z-index as 9.然后选择 z-index 为 9 的 div 的第一个孩子的第一个孩子。
  3. Then apply the style as follows:然后按如下方式应用样式:

$(element which you got).attr("style", "position: absolute; z-index: 12;")

The style will be applied to the small element and it will be visible on the red box.该样式将应用于小元素,并且在红色框上可见。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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