Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

While scrolling on an iOS device, the z-index of elements isn't working

Tags:

My layout is fairly simple, a repeating background element, a couple of vertical spaces (roads) and some horizontal bridges and a little car which should drive underneath them when you scroll.

Everything works just fine on my Mac but on iOS devices —my testing devices are: iPhone 4 on iOS 6.1, iPad 2 on iOS 6.1.3— the z-index isn't being honoured when the scroll event is active.

This means that as you scroll, the car, which is position: fixed to the window, is moving over the bridge (which has a higher z-index than the "car") rather than the z-index making the bridge higher as it should be and is on non-iOS browsers which makes the car drive under the bridge.

It seems like a simple layering issue, but even with a very simplified test case the bug is still apparent.

Test case: http://plnkr.co/EAE5AdJqJiuXgSsrfTWH (view in full screen on iPad to avoid a iframe scrolling issue which isn't related to the demo content)

Does anyone know what's wrong with the code which would cause the z-index not working while the scroll is active?

Note: This happens on both, Chrome for iOS and the native Mobile Safari.


Here are the code bits running on the reduced test case I linked to above in case someone can point out a fix without opening the demo.


HTML:

<!DOCTYPE html> <html>    <head>     <link rel="stylesheet" href="style.css">   </head>    <body>     <div class="car"></div>      <div class="street"></div>     <div class="bridge"></div>     <div class="street"></div>     <div class="bridge"></div>     <div class="street"></div>     <div class="bridge"></div>     <div class="street"></div>     <div class="bridge"></div>     <div class="street"></div>     <div class="bridge"></div>     <div class="street"></div>     <div class="bridge"></div>     <div class="street"></div>   </body>  </html> 

CSS:

body {   /* Adds the 'road' as a background image. */   background: #8BA341 url("http://f.cl.ly/items/1r2g152h2J2g3m1e1V08/road.png") repeat-y top center;   margin:     0;   padding:    0; }   .car {   /* The car's position is fixed so that it scrolls along with you. */   position:   fixed;   top:        5%;   left:       52%;   width:      220px;   height:     330px;   background: #BD6C31;   z-index:    1; } .street {   /* Empty in the example, just used to space things out a bit. */   position:   relative;   height:     500px; } .bridge {   /* A bridge crossing the main road. The car should drive under it. */   position:   relative;   height:     353px;   /* Image of repeating road. */   background: url("http://f.cl.ly/items/0u0p2k3z45242n1w3A0A/bridge-road.png") repeat-x center left;   /* Higher z-index than car. */   z-index:    2; } 
like image 223
Jannis Avatar asked Apr 16 '13 09:04

Jannis


People also ask

Why your Z-index is not working?

You set z-index on a static element By default, every element has a position of static. z-index only works on positioned elements (relative, absolute, fixed, sticky) so if you set a z-index on an element with a static position, it won't work.

Will Z-Index work for an element without position?

z-index has no effect for position:static (the default).

How do you do absolute positioning with Z-index?

Definition and Usage An element with greater stack order is always in front of an element with a lower stack order. Note: z-index only works on positioned elements (position: absolute, position: relative, position: fixed, or position: sticky) and flex items (elements that are direct children of display:flex elements).

Does Z-index have a limit?

The maximum range is ±2147483647. In CSS code bases, you'll often see z-index values of 999, 9999 or 99999. This is a perhaps lazy way to ensure that the element is always on top.


1 Answers

I believe I've solved this after much trial and error. What I did was add a webkit transform to the bridges. This allows for positive z-index numbers (car at 10, pothole at 1, bridge at 20):

new CSS:

.bridge {   -webkit-transform: translate3d(0,0,0); } 

Adding the translate to the different bridges seem to not only fix the flicker from before, but also lets you scroll immediately without any delay.

Check it out in full screen or the full Plunker. Tested on iPad iOS 6.0.1.

like image 120
Lost Left Stack Avatar answered Sep 19 '22 01:09

Lost Left Stack