Avoid z-index working relative to the parent eleme

2019-03-01 11:53发布

I come with a question about an odd behavior regarding the z-index property. The situation in terms or layers is the following:

div#wrapper
    div#sidebar (fixed position and 5 as z-index)
        div#pop-up (absolute position and 15 as z-index)
div#black-layer (fixed position and 10 as z-index)

The thing then is that I want to have a semi-transparent black layer over everything, with the next exception: over it I want another arbitrary div (depending on the case). A bit like the typical light-box.

What's happening now is that the pop-up, which is supposed to be over the black-layer, since their z-index is higher, is actually under it.

My conclusion after several tries is that the reason this occurs like so is because #pop-up is a child of #sidebar. Indeed, if I put it outside, it works as I pretend. Like:

div#wrapper
    div#sidebar
    div#pop-up
div#black-layer

But this is not a good solution at all. First because it is not semantically correct from the point of view of the HTML. And also because I have the necessity of having more "pop-ups" in other parts of the code and is not a good idea split the logic this way by keeping separately all of them.

Thank you in advantage.

Update: It is even more strange now. I haven't change anything, but just make a test in Firefox instead of Chrome, and it works there as I expected, so the pop-up is in fact over the black-layer. And also in Opera. And does not work in Maxthon. Just as a note, I'm using Linux.

标签: css z-index
1条回答
一纸荒年 Trace。
2楼-- · 2019-03-01 12:12

What's happening now is that the pop-up, which is supposed to be over the black-layer, since their z-index is higher, is actually under it.

As it perfectly well should be. z-index is perfectly well defined, for example in this part of the spec:

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.

The root element forms the root stacking context. Other stacking contexts are generated by any positioned element (including relatively positioned elements) having a computed value of 'z-index' other than 'auto'. Stacking contexts are not necessarily related to containing blocks.

Within each stacking context, the following layers are painted in back-to-front order:

  1. the background and borders of the element forming the stacking context.
  2. the child stacking contexts with negative stack levels (most negative first).
  3. the in-flow, non-inline-level, non-positioned descendants.
  4. the non-positioned floats.
  5. the in-flow, inline-level, non-positioned descendants, including inline tables and inline blocks.
  6. the child stacking contexts with stack level 0 and the positioned descendants with stack level 0.
  7. the child stacking contexts with positive stack levels (least positive first).

You are incorrectly assuming z-indexes are shared amongst the entire document, while they are only valid within their own stacking context, which is actually created for every z-indexed element - therefore your #popup is the highest element in #sidebar, but both are stacked underneath #black-layer as it is higher in the root stacking context. Older versions of IE (in quirks mode) actually used the model you are expecting, but that was fixed later on.

So, you'll need to move some elements around. Semantically, that doesn't matter at all since you'll be needing JS anyway to clone/generate the popups in practice.

查看更多
登录 后发表回答