How to resolve position:fixed for a bottom toolbar on iOS (iPhone/iPad)
Asked Answered
S

10

19

I have a bar that is fixed to the bottom of every page on my website by using position:fixed. The problem is that on devices like iPhone or iPad this property is not respected.

I tried to use javascript to detec the screen height, scroll position, and this works perfectly on the iPad:

$( window ).scroll( function ( ) { $( "#bar" ).css( "top", ( $( window ).height() + $( document ).scrollTop() - 90 ) +"px" );  } );

As you can see I'm using jQuery. The problem is that this code does not quite work on the iPhone because the window's height does not include the location bar (and also the debug bar if present), so the bar goes on the right place at first, but as you scroll it gets fixed above the right position (the amount of pixels used by Mobile Safari's location bar).

Is there a way to get this information and properly fix this toolbar?

Have in mind this is not a website made for iPhone, so I can't use tricks like iScroll at all.

Stork answered 23/3, 2011 at 18:3 Comment(3)
+1 for iPad compatible code. I'll be watching here for answers :)Rhnegative
It seems that iOS 5 solved these issues by correctly interpreting position:fixed elements.Stork
Perhaps when it comes out of Beta I'll have a look.Rhnegative
A
3

Since iOS 8.4, you can use position: sticky; respectively position: -webkit-sticky; to fix this.

Addition answered 31/3, 2016 at 11:58 Comment(1)
Sticky position is for elements to scroll with static position until reaching the top of the window, and then fixing them there. This question is for fixing an element to the bottom of the window.Swag
C
1

I can only point you in some directions:

Columbia answered 23/3, 2011 at 18:11 Comment(3)
Interesting how two of those links tell me to just give up, I wonder if this is achievable at all.Stork
If you find a solution please let us know, you can answer your own questions in SO.Columbia
distill.engineyard.com/archive#home. This site's persistant header is the least buggy I have seen. Maybe there is something they are doing that solves the issue?Imam
E
1

I just did something like this, sticking the navigation to the TOP of the window. The nav starts below the header then sticks if you scroll passed it. iOS5 does support fixed positioning. The item will snap to position AFTER scroll ends, but still works well. '#sticky-anchor' is a wrapper div around my navigation.

Don't recall where I found all this, got little pieces from many sites. You can adjust it to fit your needs.

$(window).scroll(function(event){

// sticky nav css NON mobile way
   sticky_relocate();

   var st = $(this).scrollTop();

// sticky nav iPhone android mobile way
// iOS 4 and below

   if (navigator.userAgent.match(/OS 5(_\d)+ like Mac OS X/i)) {
        //do nothing uses sticky_relocate above
   } else if ( navigator.userAgent.match(/(iPod|iPhone|iPad)/i) || navigator.userAgent.match(/Android/i) || navigator.userAgent.match(/webOS/i) ) {

        var window_top = $(window).scrollTop();
        var div_top = $('#sticky-anchor').offset().top;

        if (window_top > div_top) {
            $('#sticky').css({'top' : st , 'position' : 'absolute' });
        } else {
            $('#sticky').css({'top' : 'auto' });
        }
    };
};
Esquiline answered 12/6, 2012 at 16:20 Comment(0)
K
1

I fixed this on my site, and answered this on Stack Overflow. Since then I've gotten a ton of thanks from people who have implemented it. Sorry I don't have time for a summary.

https://mcmap.net/q/454945/-fixed-position-navbar-only-clickable-once-in-mobile-safari-on-ios5

Kluge answered 1/4, 2013 at 19:3 Comment(0)
E
0

This bit of jquery code worked for me:

if(navigator.platform == 'iPad' || navigator.platform == 'iPhone' || navigator.platform == 'iPod'){
    $("#footer_menu").css("position", "fixed").css("top", $('window').height());
};

otherwise the css for #footer_menu was:

position:fixed;
bottom:0;
width:100%;
padding:5px 0;
text-align:center;
height:44px;

I think setting the height helped with rendering properly and on a desktop browser I wanted this menu fixed to the bottom of the browser window.

Emrich answered 7/3, 2013 at 20:45 Comment(0)
O
0

Try hiding/displaying the bottom fixed nav on iPhone based on the window.innerHeight. Whenever the toolbars are displaying, usually when you scroll up, you can display the bottom nav and hide it when scrolling down, when the toolbars hide.

You can use a code like this:

    var windowHeight = {
  small: window.innerHeight,
  middle: window.innerHeight,
  big: window.innerHeight
}
window.addEventListener('resize', function(){
  var currentHeight = window.innerHeight;
  if (currentHeight < windowHeight.small) {
    windowHeight.small = currentHeight;
  }

  if (currentHeight > windowHeight.big) {
    windowHeight.big = currentHeight;
  }

  console.log('windowHeight.small', windowHeight.small, 'windowHeight.middle', windowHeight.middle, 'windowHeight.big', windowHeight.big, 'currentHeight', currentHeight);

  if (currentHeight === windowHeight.big) {
    transform(stickyNav, 'translate3d(0,120%,0)');
    console.log('Hide bottom nav on big screen!');
  } else if (currentHeight === windowHeight.middle) {
    transform(stickyNav, 'translate3d(0,0,0)');
    console.log('Show bottom nav on middle screen!');
  } else {
    transform(stickyNav, 'translate3d(0,-100%,0)');
    console.log('Display bottom nav high up on smaller screen!');
  }
})

The transform(stickyNav, 'translate3d(x,x,x)') function is a simple function taking in the bottom nav and then applying a transform in order to hide/display an item placed at the bottom.

Otilia answered 27/6, 2019 at 10:18 Comment(0)
F
0

I remember solving this using position: sticky; bottom: 0; for a container element with zero height, then using position: absolute; bottom: var(--how-much-space-u-like-below-bottom-of-screen-and-fixed-element); on the actual thing you'd like fixed to the bottom of the viewport. I believe it solved the issue at least on iOS Safari 15 and 16.

<div class="sticky-container" style="position: sticky; bottom: 0;">
  <div class="fixed-to-bottom" style="position: absolute; bottom: 1rem;">
    <button>hello world</button>
  </div>
</div>
Fatigue answered 18/12, 2022 at 13:20 Comment(0)
C
0

I used paddingBottom: 'env(safe-area-inset-bottom)',

Curriculum answered 12/4, 2024 at 11:26 Comment(1)
Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.Lactary
D
-1

iScroll probaply is the easiest solution to your problem. Contrary to your believe it also works for android and opera. The new version of it is performing superb.

http://cubiq.org/iscroll-4

Devolution answered 31/8, 2012 at 21:46 Comment(0)
E
-3

Thank Google, not me:

http://code.google.com/mobile/articles/webapp_fixed_ui.html

Pretty simple, actually.

Echino answered 29/3, 2011 at 19:22 Comment(3)
As I've mentioned since the begining: "Have in mind this is not a website made for iPhone, so I can't use tricks like iScroll at all." This is exactly that trick.Stork
The code from Google is a good starting point. However, I think it's buggy (I think the line that reads this.element = this; should be this.element = element;) and it's incomplete (several key functions are left "as exercises for the reader"). Getting the details of momentum, bounce, etc EXACTLY right are REALLY important, and that's what's been left out. I'd love to see an implementation of the missing methods!Bough
The link featured in this answer is now dead.Labialized

© 2022 - 2025 — McMap. All rights reserved.