CSS溢出时将HTML元素置于z-index的前面

Mik*_*ynn 14 html css z-index

我想将蓝色矩形容器z-index悬停在overflow该容器的元素上时,要比其他盒子更大。

第3局的z-index较大,但是我想访问Loser select下面的蓝色圆圈中的,但是我不能,除非我将鼠标悬停在蓝色矩形上方以获得焦点。

有没有一种方法可以仅使用CSS进行处理,还是需要JQuery?

我创建了一个Fiddle,它可以复制此内容,因此可以忽略任何JS错误,因为实际页面需要包含很多内容,但是问题是完整的。将鼠标悬停在第四项游戏上,该游戏具有三个下拉菜单:源,池,种子。您可以选择种子就好了。但是,将鼠标悬停在顶部的另一个游戏上,然后回到“种子”,除非再次将鼠标悬停在“游泳池”上,否则您无法选择它。无论溢出是什么,我都需要始终选择“种子”。

https://jsfiddle.net/cblaze22/qp4L15tj/8/

在此处输入图片说明

游戏悬停的当前代码(蓝色矩形区域)

.forward在蓝色矩形区域上放置了一个大的zindex。

$(element).hover(
                function () {
                    if (!$(this).parent().hasClass('editing')) {
                        $(this).addClass('forward');
                    }
                },
                function() {
                    $(this).removeClass('forward');
                }
            );
Run Code Online (Sandbox Code Playgroud)

Dec*_*erz 10

一旦您了解了结构和实际问题,实际上这是一个非常容易的修复。div的div覆盖范围。首先,在.bracket-part不需要的所有事件上禁用所有单击事件。然后,将点击事件添加回选择项。为了使其更通用以便于再次使用,您可以select在CSS选择器中简单地更改类.re-enable-events或其他内容。实际上不需要有关z-index的JS。

#bracket-wrapper .bracket-part select {
  pointer-events: all !important;
}
#bracket-wrapper .bracket-part {
  pointer-events: none;
}
Run Code Online (Sandbox Code Playgroud)

参见:https : //jsfiddle.net/uws8pf1y/

指针事件具有很好的兼容率,因此该解决方案在几乎所有设备上都应适用。


Aar*_*219 6

To get straight to the point: There is no clean CSS-only solution to your problem.
Since all your elements are pretty much identical (and by that I mean the class for example) you will not find a solution that covers all configurations. Since they do not differ from each other they all have the same z-index but not the same stacking context. Unless you give their parents a different z-index or change the stacking context you will not be able to access the blocked element. It also comes down to how limited you are with changing the code. The code looks like it has been build by JS and you just copied it to your fiddle for us to test.

Attempt #1

Attempt #1 is to just add high z-index directly to the according parent.
@mmshr already tried to do this. However, he tried to give the whole class a high z-index which is not gonna work out of course as you've already pointed out.

You could however try to only give this element a high z-index element in its style attribute. This comes down to how limited you are with changing the code. You could theoretically use JQuery for this but the way you would select the element (e.g. by nth-child()) brings me to Attempt #2 which uses the same pseudo-class and is a CSS-only attempt so using JS is nonsense in this case. By the way if you can change your code like this you could remove your little JQuery function that adds the forward class on hover.

Attempt #2

This attempt works fine and you are not limited by the ability to change code since this is pretty much one line of CSS. As already stated in Attempt #1 you could use a pseudo-class to select this element. However, this is not valid for all configurations. If you would add one element
(<div data-bind="template: { name: 'bracket-template', data: $data }">...</div>) before your blocked element you would have to change your CSS each time. But if there is no need for changing elements and configurations (or at least not the order) this is a valid solution:

#bracket-wrapper > div > div:nth-child(8) > div > div {
  z-index: 2 !important;
}
Run Code Online (Sandbox Code Playgroud)

In this attempt you can (and have to) remove your little JQuery function too:

$('.bracket-part').hover(
  function() {
    debugger;
    $(this).addClass('forward');
  },
  function() {
    $(this).removeClass('forward');
  }
);
Run Code Online (Sandbox Code Playgroud)

Remove the entire thing.

Attempt #3

Probably the cleanest and best attempt is to use the stacking context. The stacking context is explained right here. But to give you a simple overview (W3C):

Each box belongs to one stacking context. Each positioned box in a given stacking context has an integer stack level, which is its position on the z-axis relative other stack levels within the same stacking context. Boxes with greater stack levels are always formatted in front of boxes with lower stack levels. Boxes may have negative stack levels. Boxes with the same stack level in a stacking context are stacked back-to-front according to document tree order.

Most important is this part because it applies to your structure:

Boxes with the same stack level in a stacking context are stacked back-to-front according to document tree order.

If you take a look at your HTML tree you will find the following: HTML树

According to the stacking-context we should be able to give your element in the background a higher stacking-order then your element in the front by changing the order of those elements in your tree.

It is just a guess but you probably have something like an array where you store the data and some JS-file builds a tournament bracket out of it. If you could somehow change the order of those two elements (for example by changing the order of your array) you would not use CSS and would not use any additional JQuery.

What if none of these work?

Well, then I do not see any solution that requires only CSS.

I also thought about a possible JS solution but this is a tough one and I couldn't figure out a (simple) solution. Let me explain the problem:

Since your select is behind a div element JQuery would not recognize it (e.g.) on hover so you would have to use pseudo-classes again which I already covered with a CSS-only attempt.
I also thought about adding a z-index of -1 to the blocking element, because JQuery could recognize it on hover. But this leads to problems too: the blocking element is now in the background and the blocked element in the front and you can also click it. The problem is that the (former) blocking element is now behind the #bracket-wrapper. This is also not a valid solution because you would have to use a pseudo-class again to target this specific element.

Conclusion

I am gonna be honest with you: This tournament tree is poorly designed and structured. There shouldn't be overlapping elements or elements outside of a container and certainly not both in combination. If none of my attempts are suitable I do not see any CSS or JS solution. At least not a simple one. You have provided little information about how the tournament tree is build but things could change if you do.
At this state I think rebuilding this whole structure is the only really clean solution.

Edit

Solution #1 by @Deckerz

@Deckerz provided a great solution which does not focus on the z-index. Instead, it uses pointer-events. I tried this approach but failed because I forgot an important part. The logic behind it is simple:

首先,.bracket-part根据需要禁用其中所有内容的所有点击事件。然后,将点击事件添加回选择项。为了使其更通用以便于再次使用,您可以select在CSS选择器中简单地更改类.re-enable-events或其他内容。实际上不需要有关z-index的JS。

#bracket-wrapper .bracket-part select {
   pointer-events: all !important;
}
#bracket-wrapper .bracket-part {
   pointer-events: none;
}
Run Code Online (Sandbox Code Playgroud)

但是,这仍然是一种解决方法。我仍然建议重组您的代码和CSS。