0

I'm trying to implement a "scroll-then-fixed" HTML/CSS layout. The idea is that the user can scroll the page a little - until the site header is out of view - at which point the main product image on the page would be fixed to the top of the page, and the rest of the page contents would continue to scroll. Here's a mockup of what I'm trying to achieve:

Scroll then fixed mockup

As you can see, at first, the site header is visible, but the user can scroll down. When the product image (in yellow) reaches the top of the page, it becomes fixed to the top of the window.

The way I'm doing this now is to listen to the scroll event from the document (using jQuery), and then change the product image's CSS position property when the user has scrolled past the height of the header. I've tried both CSS position fixed and absolute, but each has their problems:

  1. If I switch to fixed positioning, on mobile devices (both iOS and Android) the scrolling is very smooth, and the product image is locked to the top of the window perfectly. However contents of the product image disappear if you keep your finger on the screen and the div switches from position relative to position fixed. They will redraw as soon as you release, but it looks broken while you're scrolling. This only happens on mobile devices or an emulator; not in a desktop browser. JSBin Example.
  2. If I switch to absolute positioning (and provide a top offset), I don't have the problem that the phone stops drawing the product image, however, the scrolling is really jagged. The product image jumps as you scroll. JSBin Example.

For #1, I do something like this:

  var docScrollTop = $(window).scrollTop();
  if (docScrollTop >= $('.dev-header-fixed').height()) {
    $fixableTop.css({
      'position': 'fixed',
      'top': 0,
      'z-index': 99,
      'display': 'block'
    });
  }

... and for #2, I do this:

  var docScrollTop = $(window).scrollTop();
  if (docScrollTop >= $('.dev-header-fixed').height()) {
    $fixableTop.css({
      'position': 'absolute',
      'top': docScrollTop,
      'z-index': 99,
      'display': 'block'
    });
  }

I've provided full, working JSBin example links to both approaches above. Is there some way to prevent mobile devices from hiding the contents when the switch to fixed position happens?

antun
  • 2,038
  • 2
  • 22
  • 34
  • Just an update: The problem above seems to be fixed in the latest versions of iOS, and Chrome on Android. I can reproduce it on iPhone iOS 9.0, but not iOS 11.2. I'm not sure exactly when it got fixed. – antun Mar 05 '18 at 19:01

1 Answers1

0

It's also jaggy in IE. How about using this:

if (docScrollTop >= $('.dev-header-fixed').height()) {
    console.log('Fixed header state');
    $fixableTop.css({
      'position': 'fixed',
      'top': 0,
      'z-index': 99,
      'display': 'block'
    });
yezzz
  • 2,990
  • 1
  • 10
  • 19
  • Unless I'm missing something, that's the same as #1 above. The problem with that approach is that as you're scrolling on a mobile device, when the transition to fixed position happens, the mobile browser stops drawing the contents of the fixableTop div (yellow) and it disappears. – antun Jun 04 '16 at 15:19
  • woops... sorry... looks like I was sleeping ;) – yezzz Jun 04 '16 at 18:05
  • note that both examples have the same url, that's probably why I screwed up. I have no mobile testing tools, but are you certain that with the fixed position and holding touchscreen the styles actually get updated but the browser refuses to update the screen? (only seeing the console.log should not be considered a certainty). – yezzz Jun 04 '16 at 19:22
  • I do have some ideas for the fixed style, but they would not work if the mobile browser simply does not update the screen. 1. set a class instead of inline styles. 2. trigger scroll event every 100ms or so. 3. use touchmove event 4. jquerymobile scrollstop event – yezzz Jun 04 '16 at 19:46
  • Also found this: http://stackoverflow.com/questions/29695082/mobile-web-webkit-overflow-scrolling-touch-conflicts-with-positionfixed – yezzz Jun 04 '16 at 19:46
  • Ah, thanks for catching the fact that both JSBin examples were pointing to the same URL. I just corrected that. – antun Jun 05 '16 at 14:12
  • To answer your other questions, yes I am certain that using the fixed style the styles are being updated. It works totally fine in desktop browsers; it's just on mobile ones the div disappears after the transition. – antun Jun 05 '16 at 14:13
  • ok so then the ideas above are not useful, but the stackoverflow link I gave may be a fix for the fixed position. – yezzz Jun 05 '16 at 18:18