disappearing position fixed header in ios7 mobile safari
Asked Answered
T

5

10

I've been messing with this all day and can't seem to find a fix.

I've got a simple ul that acts as a fixed header with the following css:

body {
  width: 100%;
  height: 100%;
  min-height: 100%;       
}

.stream .header {
     position: fixed;
     width: 100%;
     height: 41px;
     top: 0;
     right: 0;
     left: 0;
     z-index: 10;
     margin-bottom: 10px;
     list-style: none;
   }

The content below the header has the following css:

.stream .stream-content {
  position: relative;
  padding-top: 41px;
  -webkit-transform: translate3d(0, 0, 0);
}

When the page is scrolled in ios7 mobile safari, the following happens:

  • first scroll down -- header moves along with page top fine until scrolling is complete.

  • second scroll down -- header disappears completely and does not reappear when scrolling is complete.

  • scroll up (with header still visible) -- header disappears completely and does not reappear when the top of the page is reached.

  • scroll up (with header hidden) -- header stays hidden and does not reappear when the top of the page is reached.

  • scroll up (already at top of page with header hidden) -- header reappears and functions normally until page is scrolled down twice.

I wasn't having this issue with iOS6 mobile safari, so the issue seems related to the new url bar resizing on scroll.

Anyone else having similar issues? Suggestions welcome.

Update:

So it appears that removing -webkit-transform3d() on the header's parent (.stream) removes the issue, so there must be a conflict the way the parent div is being rendered and the header inside.

Still looking for a work around though.

Tensible answered 11/10, 2013 at 18:37 Comment(0)
S
18

I was having the same issue, it seems to be a bug that occurs when there is too much going on inside the page, I was able to fix it by adding the following transform code to the fixed position element, (transform: translateZ(0);-webkit-transform: translateZ(0);) that forces the browser to use hardware acceleration to access the device’s graphical processing unit (GPU) to make pixels fly. Web applications, on the other hand, run in the context of the browser, which lets the software do most (if not all) of the rendering, resulting in less horsepower for transitions. But the Web has been catching up, and most browser vendors now provide graphical hardware acceleration by means of particular CSS rules.

Using -webkit-transform: translate3d(0,0,0); will kick the GPU into action for the CSS transitions, making them smoother (higher FPS).

Note: translate3d(0,0,0) does nothing in terms of what you see. it moves the object by 0px in x,y and z axis. It's only a technique to force the hardware acceleration.

#header {
    position: fixed;
    /* MAGIC HAPPENS HERE */
    transform: translateZ(0);
    -moz-transform: translatez(0);
    -ms-transform: translatez(0);
    -o-transform: translatez(0);
    -webkit-transform: translateZ(0);
    -webkit-font-smoothing: antialiased; /* seems to do the same in Safari */
}
Sphenoid answered 18/9, 2014 at 23:21 Comment(1)
Thanks - arrived at the same conclusion back when I was working on this. Somewhat relevant, here's more details about the performance tradeoffs between position abs and transform translate in mobile safari: #11101247Tensible
K
0

This happens when the browser hasn't repainted the elements in time and thus, seems as if it disappears and then re-appears on scroll.

if the above answer doesn't work for you, use an infinite css animation on the element; forcing the browser to keep repainting the element.

here's the code!

@keyframes repaint {
  from {
    width: 99.999%
  }
  to {
    width: 100%;
  }
}


.positionsticky {
    animation: repaint 1ms;
  animation-iteration-count: infinite;
}
Karen answered 25/3, 2018 at 2:36 Comment(0)
B
0

I had this problem on iPhone SE. Tried the -webkit-transform: translateZ(0); trick, but it didn't help. The element I wanted to move was in the bottom of the first scroll and I wanted it to get position: fixed status after the user had scrolled to it (solved this with js). Worked everywhere else, but on SE, the element disappeared. For some reason it moved the element out of the screen, after setting top: 0, it fixed the problem for me.

.sticky_menu {
   position: fixed;
   top: 0;
}
Blindfold answered 25/6, 2019 at 23:19 Comment(0)
F
0

This is still an issue 6 years later... I tried various suggestions using css transform, but it didn't work. The only stable solution I found was adding and id to the element and then using scrollIntoView().

The scenario is a page with a top and scrolling content below. When user scrolls to the bottom, the top disappears. When user scrolls back op, it does not easily reappear. Also if the device is very small and have a text field to fill in, the top will disappear when the field is focused.

I solved it by giving the top element an id like 'topbar' and then using scrollIntoView() whenever the situation calls for it. I wrote a small function for it:

function topbarIntoView() {
  var dom = document.querySelector("#topbar");
  if (dom) {
    dom.scrollIntoView({ behavior: 'smooth', block: 'start' })
  }
}
Footlocker answered 30/7, 2020 at 18:14 Comment(0)
A
-2

I faced the same issue with iPad. I tried by adding code for iPad in JS part as:

if(navigator.userAgent.match(/iPad/i)) {
    //written code to scrolldown the header part
}

It worked for me.

Acton answered 24/10, 2016 at 6:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.