22

I'm in the process of coding a sticky notification bar seated at the bottom of a mobile screen. I want the bar to be stuck at the bottom of the users screen until the user has reached the scroll position of where the bar is actually positioned in the code (which is just before the footer of the page). I have pretty much copied the "doctor" example from this page: https://alligator.io/css/position-sticky/ My problem is: On my page, the bar works fine when using Android Devices or when simulating a mobile device by adjusting the Browser width on my Desktop Computer. However, on iOS, the bar is not sticky, i.e. it just sits at its position and doesn't stick to the bottom of the screen until reached. This applies to both Safari and Google Chrome. The weird thing is: On the previously mentioned alligator.io page, it works just fine on my iOS device.

I suspect this is some kind of Webkit problem having to do with the code surrounding the bar, but I cannot isolate it. I have tried debugging by adjusting my code as far as possible to the example from alligator.io, but I cannot get it to work. I have also tried looking for any overflow:auto in parent elements - without success. I have been trying to fix this for several hours and am sick and tired of the problem and could use another pair of eyes to help me find what I'm overlooking.

#jobalarm_mobile {
    display: table;
    font-size: 18px;
    width: 100%;
    height: 40px;
    background: #ff8400;
    color: white;
    font-weight: 400;
    text-align: center;
    position: -webkit-sticky;
    position: sticky;
    bottom: -50px;
    align-self: flex-end;
}
<a href="#" class="jobAlertToggle">
    <div id="jobalarm_mobile">
        <i class="fa fa-bell"></i>
        <span>Jobalarm aktivieren</span>
        <label class="switch">
            <input type="checkbox">
            <span class="slider round"></span>
        </label>
    </div>
</a>

You can visit the live page I am working on at (hidden on request of the customer, please contact me privately). Simply start any (suggested) search and the bar will pop up (or not, if you are using iOS...) Thanks in advance for your help.

SK-the-Learner
  • 523
  • 5
  • 18
c42
  • 761
  • 1
  • 6
  • 11

10 Answers10

39

I feel like an idiot for answering my own question, but I figured out what is causing the problem. I hope this will help developers facing the same problem because I could not find anywhere defining this behavior.

As you can see, in my code, there is a wrapper (specifically a link) around the element, on which I use my position:sticky:

<a href="#" class="jobAlertToggle">
<div id="jobalarm_mobile">
    <i class="fa fa-bell"></i>
    <span>Jobalarm aktivieren</span>
    <label class="switch">
        <input type="checkbox">
        <span class="slider round"></span>
    </label>
</div>
</a>

For some reason, this is not a problem for Chrome or Firefox on Desktop as well as Android, as they seem to ignore this container, probably because it doesn't define any positioning behavior. This is why it works on other devices. However, iOS does not ignore the container and therefor positions the div relative to its parent container, which is the link. After removing the link for test purposes, it worked on all devices.

c42
  • 761
  • 1
  • 6
  • 11
  • 6
    I had a similar problem where my wrapper was a span and by adding display:block and position: -webkit-sticky it was resolved for ios. Thanks. – taylor michels Mar 27 '19 at 20:12
  • Thanks! You saved me from some headache.. It's a really good spot, seems like iOS doesn't like wrappers around sticky elements. – Adaz Jul 10 '19 at 10:53
  • This might be caused by the div being the "only child" problem explained here: https://medium.com/@elad/css-position-sticky-how-it-really-works-54cd01dc2d46 – maganap Sep 17 '19 at 10:22
  • 1
    For what's worth I was using `position: sticky` on a pseudo- element `::before`, it worked well with Firefox and Chromium as well, but not on Safari. Adding `display: block` on the pseudo-element style along with sticky related properties, and it worked, everywhere. THANK YOU ! – bric3 May 19 '20 at 21:28
  • Similar as above comments, although for me sticky was working everywhere (including safari) except chrome on iOS where the sticky element would be hidden by the top adress bar. Using `display:block` on the parent element of sticky solved the issue. – Max May 19 '21 at 11:45
  • Encountered similar problem. On mobile devices (both safari and chrome) element with `position: sticky;` `bottom:0;` was not sticking properly. I noticed, that some content of my footer was hidden by browser toolbar, and to scroll to it I had to swipe up hardly. After that swipe sticky bottom element started working. The problem was with my `body` and `html` elements `height: 100vh`. Using `height: -webkit-fill-available` and `visibility: visible`fixed the problem. Read this article for more info: https://allthingssmitty.com/2020/05/11/css-fix-for-100vh-in-mobile-webkit/ – Sergei Kurochkin Feb 01 '22 at 16:25
8

This is the real answer

position: -webkit-sticky;
position: -moz-sticky;
position: -o-sticky;
position: -ms-sticky;
position: sticky;

and works!!!

Francis Alvin Tan
  • 1,057
  • 3
  • 21
  • 42
  • 1
    I don't know why this answer is down voted, for reference you can find similar information there https://developers.google.com/web/updates/2012/08/Stick-your-landings-position-sticky-lands-in-WebKit. Although the order is wrong, vendor prefixes should come first. Although most browsers support it now (article dates from 2012) – bric3 May 13 '20 at 19:51
  • 1
    Also not sure why this is down voted, with the correct order for vendor prefixes this worked for me (targeting this iOS specific issue) – Kevin Parker May 25 '20 at 15:31
  • Agree, this should be the accepted answer. – Jongwoo Lee Aug 10 '21 at 11:00
  • 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. – Ingo Steinke Aug 16 '22 at 13:22
  • Could someone actually say which order for vendor prefixes is correct? – Krzysztof Krzeszewski Dec 02 '22 at 11:35
4

Some of the tips in my answer here may help, notably adding display: block to your container may do the trick.

Simon_Weaver
  • 140,023
  • 84
  • 646
  • 689
1

For me nothing worked except jQuery/javascript in this way: give the element you need to be sticky position:absolute and left: 0, then use javascript to calculate offset of the window to the left, and add that offset to the left property of your element:

#stickyElement {
        position: absolute;
        left: 0;
     }

  function scrolling(){
       $('.someElementScrollingLeft').on('scroll', function() {
           let offset = $(this).scrollLeft();
           /* For me it only didn't work on phones, so checking screen size */
           if($( window ).width() <= 768)
           {
              let stickyElement = $('#stickyElement');
              stickyElement.css("left", offset);
            } 
         });
   }
Armin
  • 2,021
  • 2
  • 19
  • 17
1

In my case in full screen menu it was overflow-y: auto. I eliminated this issue by adding: overscroll-behavior: contain.

Frostbourn
  • 330
  • 3
  • 21
0

I visited a website and may be I found solution for you.

Try this it may can help you:

        #jobalarm_mobile {
             display: none !important;       
        } 

and then place your notification <a> tag at the end (after <footer> tag)

//write this css
     .jobAlertToggle{
              display: none;
           }
        @media (max-width: 767px)
          .jobAlertToggle{
              display: block;
              width: 100%;
              position:sticky;
              position:-webkit-sticky;
              bottom:-50px;
           }
    
          #jobalarm_mobile {
               display: table;
               font-size: 18px;
               width: 100%;
               height: 40px;
               background: #ff8400;
               color: white;
               font-weight: 400;
               text-align: center;
               -webkit-align-self: flex-end;
               align-self: flex-end;
           }
SK-the-Learner
  • 523
  • 5
  • 18
Hammad tariq
  • 184
  • 9
0

For my problem it was:

I had { contain: paint; } in ancestor (container above inside-container).

Changed it to { overflow: clip; }

Sticky would not work if contain: paint was present regardless of having overflow: clip.

This was tested on Iphone 15.4.1. Other tested devices didn't break with contain: paint (tested on chrome, ipad, android)

-1

I had so many problems with this issue as well. The sticky position wouldn't work on my phone - not in Safari or Chrome.

I tried placing the element that I wanted sticky in the top of the surrounding wrapper - it worked! Apparently the sticky position can't really work if there is something above it inside the same parent-wrapper. You don't have to change your order or design, you can just create a wrapper that's around the content, with the sticky element in the top.

<div class="container">
    <p>Some text above the sticky element</p>
    <div class="inside-container">
        <div class="sticky-element">
            <p>This is sticky</p>
        </div>
        <p>Some more text, that scrolls past the sticky element.</p>
    </div>
</div>
David Buck
  • 3,752
  • 35
  • 31
  • 35
MRL
  • 1
-2

I think the Problem is, that Safari (the Browser of iOS) does not support position: sticky properly. See this Article (https://caniuse.com/#feat=css-sticky). Read the Known Issues Section to find aut more. Maybe, you have to deactivate it for iOS and show a note on your Page, that its not working properly.

I hope, I could help you.

C2H6
  • 29
  • 6
  • This does however not explain why it also doesn't work on Chrome and why it works when I visit the alligator.io page on iOS – c42 Feb 12 '19 at 10:16
  • 2
    Please provide context for links. Future users may not be able to read the known issues section if the link goes dead. See how to write a good answer here: https://stackoverflow.com/help/how-to-answer – Aonghas M Feb 12 '19 at 10:16
  • @c42 are you sure the IOS version you are using supports position sticky? – Aonghas M Feb 12 '19 at 10:17
  • @Aonghas M Yes. When visiting the alligator.io page providing the example, it works fine on my iOS device. Also, in the inspector, the position:-webkit-sticky tag is active. It would be deactivated if the iOS version would not support it. – c42 Feb 12 '19 at 10:21
  • 1
    @c42 fair enough. I guess vote this answer down to show that it doesnt solve your issue then. I hope someone is able to help you soon – Aonghas M Feb 12 '19 at 10:23
-3

Use for ios position: -webkit-sticky and for other case position: sticky

user158
  • 12,852
  • 7
  • 62
  • 94