Z-index 没有覆盖 DOM 中更下方的 div

发布于 2024-09-12 23:23:52 字数 1463 浏览 5 评论 0原文

我正在尝试创建一个类似工具提示的系统,其中 mouseenter 事件会导致显示一个 div,该 div 将覆盖内容。不幸的是,我遇到的问题是 DOM 中稍后的内容在 IE7 中不会消失,而之前的内容在 z 索引元素后面正确消失。

这是一些说明问题的示例代码:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<body>

<style>
  .container { margin-top: 200px; }
  .node { float: left; width: 100px; height: 100px; background: #eee; margin-right: 50px; position: relative;}
  .two { position: absolute; left: -200px; top: 20px; width: 500px; height: 500px; background: green; z-index: 200;}
</style>

<div class="container">
<div class="node">
  <div class="one"></div>
</div>
<div class="node">
  <div class="two"></div>
</div>
<div class="node">
  <div class="three"></div>
</div>
</div>
</body>
</html>

要点相当简单。 3个相同的灰色盒子。除了其中一个框中有工具提示(巨大的绿色框)。如果您在 Firefox 中查看此内容,效果很好。如果您在 IE7 中查看它,您会注意到绿色框覆盖了第一个节点、第二个节点,但第三个节点显示出来。此外,如果您在 .node 上设置 z-index: 1 属性,您会发现即使在 Firefox 中它也表现出相同的行为。

解决方案

感谢下面的回复,我能够走上正确的轨道。首先,将所有工具提示的 z-index 设置为最高元素。然后将所有节点元素的 z-index 设置为较小的数字。我使用了 10 和 0。接下来,在悬停时,设置最高兄弟元素的 z-index 需要高于它的兄弟元素,我使用了 5。在这种情况下,如果我希望 .child2 位于所有内容之上,那么我需要设置最高父级的 z-index,它是我想要覆盖的所有内容的兄弟(这可能是链上的多个父级)。在本例中,它是节点。因此包含 .two 的节点的 z 索引需要高于另一个 .node 的 z 索引。同样,如果工具提示位于节点 ->子节点->工具提示并且该节点与相似的树相邻,那么我需要设置节点 z-index(2 个父节点)。

I'm attempting to create a tooltip-like system where a mouseenter event causes a div to show up which will overlay content. Unfortunately the issue I've run into is that content later in the DOM is not disappearing in IE7, while content earlier is disappearing correctly behind the z-indexed element.

Here is some sample code which illustrates the problem:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<body>

<style>
  .container { margin-top: 200px; }
  .node { float: left; width: 100px; height: 100px; background: #eee; margin-right: 50px; position: relative;}
  .two { position: absolute; left: -200px; top: 20px; width: 500px; height: 500px; background: green; z-index: 200;}
</style>

<div class="container">
<div class="node">
  <div class="one"></div>
</div>
<div class="node">
  <div class="two"></div>
</div>
<div class="node">
  <div class="three"></div>
</div>
</div>
</body>
</html>

The gist is rather simple. 3 identical gray boxes. Except in one of those boxes there is the tooltip (the giant green box). If you view this in Firefox, it works fine. If you view it in IE7 you'll notice that the green box overlays the first node, the second node, but the third node shows through. In addition if you set the z-index: 1 property on .node you'll notice that it exhibits the same behavior even in Firefox.

SOLUTION

Thanks to the response below I was able to get aligned on the right track. First, set the z-index of all tooltips to the highest element. Then set the z-index of all of the node elements to a lower number. I used 10 and 0. Next, on hover, set the z-index of the highest brother element needs to be higher than it's brothers, I used 5. In this case, if I want .child2 to be on top of everything, then I need to set the z-index of the highest parent which is a brother to everything I want to overlay (this could be multiple parents up the chain). In this case, it is node. So the z-index of the node which contains .two needs to be higher than the z-index of the other .node. Likewise, if the tooltip was at node -> subnode -> tooltip and that node was adjacent to similar trees, then I would need to set the node z-index (2 parents up).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

我是男神闪亮亮 2024-09-19 23:23:52

如果未设置,较旧的 IE 会以 z 索引 0 启动每个新的位置堆栈(而不是关注节点的父节点)——结果是标记中的最后一个节点总是掩盖较早的节点。

为了强制较旧的 IE 在此类情况下运行,您必须为所有节点在它们共有的最深嵌套级别定义显式 z-index 值,并且它们必须随着您在文档中移动而下降。完成此操作后,您可以在所有同级之前从组中提取任何项目。

在您的示例中采取较小的自由度来简化,假设您有这样的标记:

<div class="container">
 <div class="node1">
  <div class="child1"></div>
 </div>
 <div class="node2">
  <div class="child2"></div>
 </div>
 <div class="node3">
  <div class="child3"></div>
 </div>
</div>

您希望在整个页面中按降序对“nodeX”元素进行 z 索引(它们必须全部位于相同的嵌套级别),然后你可以给他们的孩子 z-index 值,这将是有意义的。

你的基本 CSS 应该是这样的:

/* parent nodes in descending order at same nest level */
.node1 { z-index: 99; }
.node2 { z-index: 98; }
.node3 { z-index: 97; }

/* child nodes contain tooltip data, z-index higher than parent */
.child1 { z-index: 101; display: none; }
.child2 { z-index: 101; display: none; }
.child3 { z-index: 101; display: none; }

...当你想要将其中一个子项显示为工具提示时,你需要将其父项 z-index 设置为高于其他父项。在本例中,我们要激活工具提示 .child2,它位于 .node2 内:

.node2 { z-index: 100; }
.child2 { display: block; }

当您将 .node2 设置为位于所有其他“.nodeX”项目上方的 z 索引时,它(及其子项)应该能够遮盖同一嵌套级别的节点。

自动化流程

显然,这可能是一个很大的痛苦设置......它很简单,可以在需要重叠的小型硬编码下拉菜单之类的东西上设置一些手动条目,但是如果您正在动态生成页面,那么您可能足够聪明,可以使用 javascript 来帮助您。

重要的是,降序的 z-index 值必须全部位于 DOM 树中的相同嵌套级别,这一点我怎么强调都不为过。要为示例中的所有 nodeX 元素设置降序值(从 99 开始),我可能会使用如下所示的一些 jQuery 代码:

$(document).ready( function() {
    var zidx = 99;
    $('.container>div').each( function() {
        $(this).css('z-index',zidx);
        zidx--;
    });
});

基本上,我们只是循环遍历特定级别的元素,并为每个后续元素提供一个 z 索引,即低一个。显然,您需要注意可能使用的元素数量并相应地选择范围。

Older IEs kicks off each new positional stack with a z-index of 0 if it's not set (rather than paying attention to a node's parent) -- the result is the last nodes in the markup always obscure earlier nodes.

In order to force older IEs to behave in cases like these, you must define a explicit z-index value for all nodes at the deepest nesting level they all have in common, and they must descend as you move through the document. Once you've done this, you can pull any item from the group ahead of all its peers.

Taking minor freedom with your example to simplify, let's say you had markup like this:

<div class="container">
 <div class="node1">
  <div class="child1"></div>
 </div>
 <div class="node2">
  <div class="child2"></div>
 </div>
 <div class="node3">
  <div class="child3"></div>
 </div>
</div>

You would want to z-index the "nodeX" elements in descending order down the entire page (they must all be at the same nesting level), and then you can give their children z-index values which will make sense.

Your base CSS would be like this:

/* parent nodes in descending order at same nest level */
.node1 { z-index: 99; }
.node2 { z-index: 98; }
.node3 { z-index: 97; }

/* child nodes contain tooltip data, z-index higher than parent */
.child1 { z-index: 101; display: none; }
.child2 { z-index: 101; display: none; }
.child3 { z-index: 101; display: none; }

... and when you want to display one of the child items as a tooltip, you would need to set its parent z-index above the other parents. In this case we want to activate the tooltip .child2, which lives inside .node2:

.node2 { z-index: 100; }
.child2 { display: block; }

When you set the .node2 to a z-index above all the other ".nodeX" items, it (and its children) should be able to obscure the nodes at the same nesting level.

Automating the Process

This can be a major pain to set up, obviously ... it's simple enough to set a few manual entries on something like a small hardcoded dropdown menu that needs to overlap itself, but if you are dynamically generating the page then you are probably savvy enough to use javascript to help you out.

The important thing is that the descending z-index values must all be at the same nesting level in your DOM tree, I can't stress this enough. To set the descending values for all of our nodeX elements in the example (starting at 99), I might use some jQuery code like this:

$(document).ready( function() {
    var zidx = 99;
    $('.container>div').each( function() {
        $(this).css('z-index',zidx);
        zidx--;
    });
});

Basically we just loop through elements at the specific level and give each subsequent element a z-index that is one lower. Obviously you'll need to pay attention to how many elements you might use and choose a range accordingly.

貪欢 2024-09-19 23:23:52

IE 错误地实现了堆叠顺序算法。您必须动态更改“当前”工具提示的 z 索引,以便无论哪个是活动 .node,都给它一个 z 索引,例如 10,当打开另一个工具提示时,将其重新分配给初始值。

据我所知,不改变源代码顺序就没有真正的 CSS 解决方案。

IE incorrectly implements the stacking order algorithm. You'll have to dynamically alter the z-index of the "current" tooltip so whichever is the active .node, give it a z-index of say, 10 and when another tooltip is opened, reassign it to the initial value.

To my knowledge there is no true CSS solution without altering the source order.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文