Reputation: 374
I'm seeing some interesting z-index behaviour on iOS.
My sample code can be viewed here: https://jsfiddle.net/59mo8s16/4/
I need the #sidebar
to be displayed in front of the #slide-in-tip
. This is the case when viewed on Chrome (PC and Android) and Firefox (PC). However, on iOS Safari and Chrome, #slide-in-tip
appears in front of #sidebar
.
I've realised that removing -webkit-overflow-scrolling: touch
from the CSS makes it appear as intended across all platforms/browsers. However, I need this in order to provide momentum scrolling for the #container
div on iOS. Without it, you get that scrolling that stops as soon as you stop swiping, which provides a terrible user experience.
Any ideas on how to resolve this one? Ideally I'd like a CSS-only solution. Any significant restructure of HTML will cause me some major pain at this point. The sample is a really stripped back version of an already-complete website.
HTML:
html,
body {
height: 100%;
margin: 0;
-webkit-overflow-scrolling: touch;
}
#top-bar {
top: 0;
width: 100%;
z-index: 200;
background-color: green;
height: 85px;
position: absolute;
}
#sidebar {
float: left;
padding: 30px;
background-color: pink;
position: fixed;
width: 310px;
left: 0px;
z-index: 150;
top: 85px;
bottom: 0px;
padding: 0;
padding-bottom: 50px;
}
#container2 {
min-height: 100%;
}
#main {
padding-right: 20px;
height: 100%;
margin: 0;
margin-left: 10%;
line-height: 40px;
text-align: right;
}
#container {
height: 100%;
margin: 0;
position: absolute;
width: 100%;
overflow-y: scroll;
}
#container2 {
padding-top: 75px;
}
#slide-in-tip {
position: fixed;
bottom: 0;
text-align: right;
width: 100%;
z-index: 140;
background-color: blue;
height: 200px;
}
<div id="top-bar">
top-bar
</div>
<div id="container">
<div id="container2">
<div id="sidebar">
sidebar
</div>
<div id="main">
long content - see js fiddle for actual long content
</div>
</div>
</div>
<div id="slide-in-tip">
slide-in-tip
</div>
Upvotes: 4
Views: 2065
Reputation: 724372
The documentation offers an explanation for the behaviour you're seeing:
touch
Native-style scrolling. Specifying this style has the effect of creating a stacking context (like opacity, masks, and transforms).
Since you cannot destroy a stacking context after creating one, an element outside of a stacking context cannot interact directly with elements within that stacking context, and you cannot move elements between stacking contexts without moving them physically, you won't be able to work around the stacking issues without restructuring your physical HTML.
Having said that, you shouldn't have to make significant changes to your structure. The best you can do is simply move #slide-in-tip
into #container2
as a sibling of #sidebar
and #main
(where exactly you place it doesn't matter, as long as they are all siblings). For whatever reason, though, this seems to cause severe flickering on scroll in the simulator — I don't have a physical device to test this on, so you'll want to test this thoroughly.
The only CSS-based workaround I can offer is to shorten your #slide-in-tip
by giving it a left
offset equal to the width of #sidebar
. Note that you have conflicting padding
declarations in your #sidebar
rule such that the width of #sidebar
is actually 310px, not 370px. Unfortunately, if portions of #sidebar
are transparent and you want #slide-in-tip
to be seen through those transparent portions, this will not be an option either.
Upvotes: 2