4

This seems to be a brainer, but I'll give it a try:

I have a nested element that is position:fixed (.inside) inside another element (.bottom) which is fixed as well and has overflow:hidden. I need to get the nested element get out the hidden one AND overlapping another element (.top) with an higher z-index as the parent element. This means: .inside should overlay everything.

Unfortunatly I cannot change the HTML scope nor the z-index values of .top and .bottom. And of course not the overflow: hidden

Here's the markup:

<div class="header">
  <div class="top"></div>
  <div class="bottom">
    <div class="inside"></div>
  </div>
</div>

… and the CSS:

body {
    margin: 0;
    padding: 0;
}

.header {
    position: relative;
    z-index: 1;
}

.top {
    background: aqua;
    height: 40px;
    opacity: 0.5;
    position: fixed; /* important – do not change! */
    width: 100%;
    z-index: 5; /* important – do not change! */
}

.bottom {
    background: green;
    height: 40px;
    overflow: hidden; /* important – do not change! */
    position: fixed; /* important – do not change! */
    top: 40px;
    width: 100%;
    z-index: 3; /* important – do not change! */
}

.inside {
    background: red;
    height: 40px;
    position: fixed; /* important – do not change! */
    top: 20px;
    width: 100px;
    z-index: 10; /* doesn't work! */
}

Here's the fiddle: http://jsfiddle.net/c7qqtu95/1/

elf acht
  • 41
  • 1
  • 5

1 Answers1

4

Your nested element is within its parent's stacking context

Applying overflow: hidden to a parent with a fixed-position child usually doesn't hide the child. But the parent element's stacking context does have an effect on its fixed-position child elements.

The issue is that .inside is not independently indexed on the 'z' axis because it is part of the stacking context of its parent .bottom, which has its own z-index applied. Even without a defined z-index, .bottom would create a new stacking context because it also has position: fixed.

According to MDN's documentation on stacking context:

  • Positioning and assigning a z-index value to an HTML element creates a stacking context, (as does assigning non-full opacity).
  • Stacking contexts can be contained in other stacking contexts, and together create a hierarchy of stacking contexts.
  • Each stacking context is completely independent from its siblings: only descendant elements are considered when stacking is processed.
  • Each stacking context is self-contained: after the element's contents are stacked, the whole element is considered in the stacking order of the parent stacking context.

You'd have to remove position: fixed and z-index from .bottom for .inside to be within the same stacking context of .top.

Then your only recourse would be to use position: absolute on .bottom, at which point two of three of the properties you indicated with /* important — do not change! */ will have been changed.

If you cannot accommodate these changes, or edit the HTML, then you have no recourse.

body {
    margin: 0;
    padding: 0;
}

.header {
    position: relative;
    z-index: 1;
}

.top {
    background: aqua;
    height: 40px;
    opacity: 0.5;
    position: fixed; /* important – do not change! */
    width: 100%;
    z-index: 5; /* important – do not change! */
}

.bottom {
    background: green;
    height: 40px;
    overflow: hidden; /* important – do not change! */
    /*position: fixed; *//* important – do not change! */
    position: absolute;
    top: 40px;
    width: 100%;
    /* z-index: 3; *//* important – do not change! */
}

.inside {
    background: red;
    height: 40px;
    position: fixed; /* important – do not change! */
    top: 20px;
    width: 100px;
    z-index: 10; /* this works now! */
}
<div class="header">
    <div class="top"></div>
    <div class="bottom">
        <div class="inside"></div>
    </div>
</div>
gfullam
  • 11,531
  • 5
  • 50
  • 64
  • so basically this is just never possible in ios? because i have it working in every browser except for ios chrome and safari. i have search page that has a drawer that is `position: fixed`, and focusing search input triggers the inputs containing element to become a `position: fixed` autocomplete. it works every where except ios, in ios the thing comes up invisible, only thing you can see is the cursor. crazy. – r3wt Feb 27 '19 at 20:49
  • 1
    @r3wt I can't say without more info. But with a [Minimal, Complete, and Verifiable example](https://stackoverflow.com/help/mcve), you could have a great SO question of your own. – gfullam Mar 01 '19 at 21:27