35

I know iPhones used to not support position:fixed, but now it does and I'm seeing a weird glitch when I scroll a fixed position element behind other elements with higher z-index. The fixed positions element with the lower z-index appears in front momentarily, which looks really bad. Is there a way to prevent this?

I tried adding -webkit-transform: translate3d(0, 0, 0); to the fixed element and it doesn't seem to help this problem.

Here is a jsfiddle as well.

Update I added transform:translateZ(x) in addition to the z-index and it did not fix the problem.

Update2 I added -webkit prefix and this DOES fix the z-index problem on an mobile Safari, but also causes the position:fixed to work incorrectly in desktop Chrome.

emersonthis
  • 32,822
  • 59
  • 210
  • 375
  • Try using `-webkit-backface-visibility: hidden;` – Hardy Dec 30 '13 at 02:37
  • 1
    On the fixed element? I tried adding it to the fixed element and it did not solve the problem. – emersonthis Dec 30 '13 at 03:35
  • Yes, on fixed element. It should remove some glitch. Any help? – Hardy Dec 30 '13 at 12:43
  • @Hardy Unfortunately no. I updated the live demo if you want to check. – emersonthis Dec 30 '13 at 14:29
  • @JacquesGoulet The all the code is visible by inspecting the source of the live demo. Let me know if you have more questions. – emersonthis Jan 02 '14 at 16:34
  • @JacquesGoulet That location is not live... It's a demo. It's there specifically for this purpose. – emersonthis Jan 02 '14 at 16:41
  • @JacquesGoulet I thought your comment was about logistics as opposed to "The Rules". I was expecting to post relevant code as soon as we had any specifics for what that was. In the mean time, I don't see how posting ALL the source into this thread will be more useful than inspecting the source directly. Do you think that will actually help you (now or for posterity)? If so I'll do it, but if this is just about adhering to the *letter* (and not the spirit) of the rule, I think there are more constructive things to we could be doing. – emersonthis Jan 02 '14 at 16:58
  • @JacquesGoulet the jsFiddle is a good thought but I'm not able to view it properly on an iPhone. Are you? – emersonthis Jan 03 '14 at 01:51
  • @JacquesGoulet I still can't figure out how to view the jsFiddle on an iPhone. What's the connection between steps 1/2 and 3/4? – emersonthis Jan 07 '14 at 17:43
  • @JacquesGoulet for me jsfiddle.net/draft is an empty page. – emersonthis Jan 07 '14 at 17:44
  • 2
    Got it! +1 for that cool trick! – emersonthis Jan 07 '14 at 20:41
  • http://cssuseragent.org/ that will add classes like `.ua-safari` to the body – HandiworkNYC.com Mar 10 '17 at 18:27

4 Answers4

42

z-index is not reliable with position:fixed, as shown in this fiddle: http://jsfiddle.net/mZMkE/2/ use translateZ transformation instead.

transform:translateZ(1px);

on your page elements.

EDIT: In your code, Add this css:

.bla, .projects, .contact  {
      -webkit-transform:translateZ(1px);
      -moz-transform:translateZ(1px);
      -o-transform:translateZ(1px);
      transform:translateZ(1px);
}

and then remove z-index refs from those elements and .intro.

tnt-rox
  • 5,400
  • 2
  • 38
  • 52
  • 1
    Can you elaborate a bit? What do you mean by "page elements"? Do you mean use the `translateZ` in place of z-index with increasing valued? – emersonthis Jan 03 '14 at 13:40
  • I added `transform:translateZ(x)` in addition to the z-index and it did not fix the problem. – emersonthis Jan 04 '14 at 11:46
  • The fiddle explains the behavior and the fix. you can remove the z-index all together and replace with -webkit-transform:translateZ(n). this also activates hardware acceleration. – tnt-rox Jan 05 '14 at 06:17
  • Did you see my comment above? adding that style seems to disable the `position:fixed`, at least on iPhones. – emersonthis Jan 05 '14 at 13:07
  • I'm not getting the same result as you. The position is fixed in my fiddle; and stays that way on all devices I've tested it on! – tnt-rox Jan 06 '14 at 13:53
  • I can't figure out how to view your jsfiddle from an iPhone. Are you able to do this? If so, how? – emersonthis Jan 07 '14 at 17:44
  • @SDP - The effect will be the same across all browsers. All you need to do is attach the transform:translateZ(1px) css lines to your page elements... in your code
    etc. and then remove the z-index's in your css.
    – tnt-rox Jan 08 '14 at 06:30
  • Apparently this is outdated, as this fiddle does not work as intended. iOS 9.2. – ffxsam Jan 20 '16 at 23:55
  • maybe you could check what's wrong with this site http://bp.sahradyan.com/. Click red button Liitu Pakkumistega. I tried like everything. Still having troubles with scrolling. Thank you in advance. – Aram Sahradyan Nov 29 '17 at 02:32
  • i know this answer was provided half a decade ago, but im still noticing issues with the combination of `z-index` and `position: fixed` on Chrome desktop. does the issue still exist to this day? more importantly, does this solution still work to this day? – oldboy Oct 28 '20 at 03:45
5

Update 1: I added transform:translateZ(x) in addition to the z-index and it did not fix the problem.

Update 2: I added -webkit- prefix and this DOES fix the z-index problem on mobile Safari, but also causes the position:fixed to work incorrectly in desktop Chrome. "

Then try to wrap -webkit-transform:translateZ(x) in a mobile specific media query.
For example:

@media only screen and (min-device-width : ... ) and (max-device-width : ... ) {
    .whatever {
        -webkit-transform: translateZ(x)
    }
}

So in this case it won't do anything on desktop Chrome

Community
  • 1
  • 1
Barnee
  • 3,212
  • 8
  • 41
  • 53
3

I tried the solution accepted as an answer in a specific case when I needed to set different position in the stack of different layers, but that alone didn't work both in desktop browsers (firefox and chrome) and Safari iOS

I came out with this hack which uses both translateZ and z-index for each div, which is working in those platforms. The order of translateZ and z-index is important. For setting each layers position is

-webkit-transform:translateZ(1px);
-moz-transform:translateZ(1px);
-o-transform:translateZ(1px);
transform:translateZ(1px);
position: relative; 
z-index: 1; 

I used the same value for the z-index and translateZ just for consistency, it is not necessary. See working example http://jsbin.com/peyehufo/5

cagnarrogna
  • 85
  • 1
  • 7
2

I'm not advocating for this solution, but it's the best I've got at the moment...

In order to replicate the effect of z-index with position fixed on an iPhone, it seems to require two techniques together:

  1. As suggested by @tnt above, use transform:translateZ(n) where z-index is used to get mobile safari to handle the stack order correctly. This appears to have the unfortunate side-effect of causing the position:fixed to stop working...

  2. Instead of position:fixed, use a javascript technique like this to fake it.

I haven't tested this thoroughly (because I'm not going to do it), but it seems to work fairly well. Although the "fixed" element seems to stutter a bit.

emersonthis
  • 32,822
  • 59
  • 210
  • 375