The issue of overflow scrolling not functioning properly on fixed-positioned elements in iOS is

On mobile devices / sizes, I have a navigation bar with position: fixed at the bottom of a page. The nav bar includes an overflow container for scrolling right to see more links (although I personally believe this design choice leads to poor user experience).

The problem arises when testing on iOS devices - if the top/bottom native browser elements are not on screen and auto-hide, the fixed behavior stops working. To demonstrate the issue, I've provided a link to the fiddle below along with relevant code snippets:

Check out the behavior in question on this Fiddle

.sticky-nav {
  position: fixed;
  width: 100%;
  bottom: 0;
  left: 0;
  z-index: 90;
  background-color: #ddd;
  border-top: 1px solid #f8f8f8;
  overflow: hidden;
}

.sticky-nav-inner {
  display: -webkit-flex;
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 90%;
  height: 57px;
  max-width: 1200px;
  margin: 0 auto;
  z-index: 0;
}

.sticky-nav-menu {
  display: inline-block;
  white-space: nowrap;
  padding-right: 25px;
  margin: 0;
}

.sticky-nav-menu li {
  display: inline-block;
  white-space: nowrap;
  margin-right: 25px;
  padding-top: 20px;
}

.sticky-nav-overflow {
  width: calc(100% - 100px);
  height: 100%;
  margin-right: 2%;
  overflow-x: scroll;
}

.sticky-nav-mobile {
  padding-left: 1%;
  z-index: 1;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet"/>
<div class="pane-container">
      <nav class="sticky-nav js-sticky-nav clearfix">
        <div class="sticky-nav-inner">
          <div class="sticky-nav-overflow">
            <ul role="tablist" class="sticky-nav-menu is-centered-text">
              <li role="presentation" class="active"><a href="#linkone" aria-controls="linkone" role="tab" data-toggle="tab" class="sticky-nav-link">LINK ONE</a></li>
              <li role="presentation"><a href="#linktwo" aria-controls="linktwo" role="tab" data-toggle="tab" class="sticky-nav-link">LINK TWO</a></li>
              <li role="presentation"><a href="#linkthree" aria-controls="linkthree" role="tab" data-toggle="tab" class="sticky-nav-link">LINK THREE</a></li>
              <li role="presentation" class="sticky-nav-animated-list"><a href="#linkfour" aria-controls="linkfour" role="tab" data-toggle="tab" class="sticky-nav-link">LINK FOUR</a></li>
            </ul>
          </div>
          <div class="sticky-nav-mobile">
            <a href="#" class="sticky-nav-cta call-button">BUY NOW</a>
          </div>
        </div>
      </nav>
      <div class="tab-content">
        <div id="linkone" role="tabpanel" class="grid-container grid-parent linkone-pane is-centered-text tab-pane fade in active">
          <h1>Link one pane</h1>
        </div>
        <div id="linktwo" role="tab-panel" class="grid-container grid-parent linktwo-pane is-centered-text tab-pane fade">
          <h1>Link two pane</h1>
        </div>
        <div id="linkthree" role="tab-panel" class="grid-container grid-parent linkthree-pane is-centered-text tab-pane fade">
          <h1>Link three pane</h1>
        </div>
        <div id="linkfour" role="tab-panel" class="grid-container grid-parent linkfour-pane is-centered-text tab-pane fade">
          <h1>Link four pane</h1>
        </div>
      </div>
    </div>

Despite trying alternatives like -webkit-overflow-scrolling, the issue persists. It seems that the issue lies in how iOS treats the area outside the view without its native bottom bar pushing up.

Your help in resolving this matter would be greatly appreciated. I've exhausted my options and am open to using JavaScript solutions. Thank you for any assistance you can provide!

Answer №1

Referenced from this source.

Utilizing the overflow: scroll; property alongside -webkit-overflow-scrolling: touch; can greatly enhance the scrolling behavior on mobile websites. It transforms the clunky scrolling experience into a smooth and expected one.

If you encounter issues with unscrollable content within a div styled with -webkit-overflow-scrolling: touch; when dynamically adding content that exceeds its height, a workaround is to include an inner div that slightly surpasses the outer div in height to trigger the scrollbar:

.outer {
  overflow: scroll;
  -webkit-overflow-scrolling: touch;
  /* Additional properties for fixed height ... */
}

.inner {
  height: calc(100% + 1px);
}

This method has not been personally verified yet.

Answer №2

There is an issue on iOS where browsers like Safari and Chrome incorrectly calculate the width of dynamically added content after the DOM has loaded. This can cause problems such as the inability to scroll on mobile iOS devices when using a library like pagination.js on a table. One possible solution is adding the following CSS after modifying the content:

min-height:1000px

Answer №3

After some investigation, I managed to fix the issue (which was quite unusual). It turned out that having the navigation fixed to the very bottom was causing the problem. To resolve this, I adjusted the spacing using the bottom property and included a pseudo-element to fill the gap. Additionally, I increased the height of the link elements within the scroll container. Here is the revised code snippet:

.sticky-nav {
  position: fixed;
  width: 100%;
  padding-top: 10px;
  bottom: 10px;
  left: 0;
  z-index: 90;
  background-color: #ddd;
  border-top: 1px solid #f8f8f8;
}

.sticky-nav:after {
  content: "";
  position: absolute;
  width: 100%;
  height: 10px;
  bottom: -10px;
  left: 0;
  background-color: #ddd;
}

.sticky-nav-inner {
  display: -webkit-flex;
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 90%;
  height: 57px;
  max-width: 1200px;
  margin: 0 auto;
  z-index: 0;
}

.sticky-nav-menu {
  display: inline-block;
  white-space: nowrap;
  height: 100%;
  padding-right: 25px;
  margin: 0;
}

.sticky-nav-menu li {
  display: inline-block;
  white-space: nowrap;
  height: 100%;
}

.sticky-nav-menu li a {
  display: inline-block;
  height: 100%;
  padding-top: 20px;
  padding-right: 25px;
}

.sticky-nav-overflow {
  width: calc(100% - 100px);
  height: 100%;
  margin-right: 2%;
  overflow-x: scroll;
}

.sticky-nav-mobile {
  padding-left: 1%;
  z-index: 1;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet"/>
<div class="pane-container">
      <nav class="sticky-nav js-sticky-nav clearfix">
        <div class="sticky-nav-inner">
          <div class="sticky-nav-overflow">
            <ul role="tablist" class="sticky-nav-menu is-centered-text">
              <li role="presentation" class="active"><a href="#linkone" aria-controls="linkone" role="tab" data-toggle="tab" class="sticky-nav-link">LINK ONE</a></li>
              <li role="presentation"><a href="#linktwo" aria-controls="linktwo" role="tab" data-toggle="tab" class="sticky-nav-link">LINK TWO</a></li>
              <li role="presentation"><a href="#linkthree" aria-controls="linkthree" role="tab" data-toggle="tab" class="sticky-nav-link">LINK THREE</a></li>
              <li role="presentation" class="sticky-nav-animated-list"><a href="#linkfour" aria-controls="linkfour" role="tab" data-toggle="tab" class="sticky-nav-link">LINK FOUR</a></li>
            </ul>
          </div>
          <div class="sticky-nav-mobile">
            <a href="#" class="sticky-nav-cta call-button">BUY NOW</a>
          </div>
        </div>
      </nav>
      <div class="tab-content">
        <div id="linkone" role="tabpanel" class="grid-container grid-parent linkone-pane is-centered-text tab-pane fade in active">
          <h1>Link one pane</h1>
        </div>
        <div id="linktwo" role="tab-panel" class="grid-container grid-parent linktwo-pane is-centered-text tab-pane fade">
          <h1>Link two pane</h1>
        </div>
        <div id="linkthree" role="tab-panel" class="grid-container grid-parent linkthree-pane is-centered-text tab-pane fade">
          <h1>Link three pane</h1>
        </div>
        <div id="linkfour" role="tab-panel" class="grid-container grid-parent linkfour-pane is-centered-text tab-pane fade">
          <h1>Link four pane</h1>
        </div>
      </div>
    </div>

Answer №4

Experiencing similar challenges like yours upon apple's iOS10 update, I found your solution to be the key! The footer in my app (developed with meteor and running on an iPhone 7 with iOS 10) was failing to stick to the bottom. Thankfully, a more concise fix worked for me.

For my footer div, I simply added a class with

position: fixed; and bottom: 0px;
. When using bottom: 0;, the footer now remains at the bottom regardless of the content scrolling.

I trust this can assist others facing the same dilemma.

Answer №5

This is the method I used to resolve the issue.

I implemented a function to detect when scrolling has ceased. Once the scrolling stops, I then apply the CSS property position:fixed to the header/footer elements.

var stopScroll = function(callback) {
    // Check if a valid callback was provided
    if (!callback || Object.prototype.toString.call(callback) !== '[object Function]') return;
    
    var scrollTimer;
    
    window.addEventListener('scroll', function(event) {
        $("header").css("position", "absolute");
        
        window.clearTimeout(scrollTimer);
        
        scrollTimer = setTimeout(function() {
            callback();
        }, 66);
    }, false);
};

// Usage example
stopScroll(function() {
    $("header").css("position", "fixed");
    console.log("Scrolling has stopped.");
});

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

modifying output of data when onchange event is triggered

I am struggling with creating an onchange event for my option box in which the users of a site are listed. I have two input boxes designated for wins and losses, but the output is not changing when I select a user from the list. What could be wrong with my ...

How to modify a Python script to print in a specific div element instead of the Chrome console?

Currently conducting preliminary tests on executing a Python script within a Chrome extension. The code provided below is functional, but I am seeking assistance on how to display the value in a div element instead of logging it to the console. Unfortunate ...

Display the chosen rows from an HTML table

I currently have a table set up like the one shown in this example. I am now looking to add a feature that allows users to print only selected rows. These rows should be selectable by clicking on checkboxes located on the right side of each row. If anyone ...

Issues with Bootstrap split button display malfunctioning

Experiencing an issue with a Bootstrap split button while working on a test Drupal website. Although it seems to be working fine in Codepen and JSFiddle, on this particular website, the dropdown component appears to be getting pushed under the button. Desp ...

Choosing several options from a list with React Native

I have a list created using the data.map() method, but I am encountering an issue where it only allows selection of one item at a time. I actually want to be able to select multiple items from the list. Even though I had designed the list to allow selectin ...

How to effectively utilize $emit in Angular?

Whenever I use {{callData}} in my HTML, the result of $scope.callData doesn't seem to be functioning properly. Is there something wrong with my code? I would greatly appreciate any help in resolving this issue. phonecatControllers.controller(&apos ...

JQuery functionality not functioning properly following an AJAX page reload

Currently, I am utilizing a jQuery code to select all checkboxes in the following manner: var JQ7=jQuery.noConflict(); JQ7(document).ready(function(){ JQ7("#chkAll").click(function(){ JQ7(".chk").prop("checked",JQ7("#chkAll").prop("checked")) }) }); ...

implementing dynamic navigation bar, when transforming into a dropdown menu using ReactJS

I am currently utilizing a navigation bar from a Bootstrap theme within my React project. The navigation bar includes an in-built media query that determines whether it should display as a dropdown menu or not, with a toggler to handle the dropdown functi ...

Is React-Apollo encountering a 404 network error?

I am currently exploring React-apollo and attempting to implement Server-side rendering with apollo, but I keep encountering a 404 error. Despite confirming that my graphQL endpoint is functional. Here is the specific error message: { Error: Network erro ...

Steps for adding JSON array information to the tbody of an HTML table

I am a beginner in the world of jQuery and JSON, seeking guidance on parsing a JSON file in order to populate an HTML table's tbody section: {"response":[["name0","id0","amt0"],["name1","id1","amt1"]]} I am struggling to figure out how to access thi ...

Modify the state of an individual item within an array

I have a list of items that I need to show a loader for and hide it once a certain action is completed. For instance, below is my array of items: [ { "id": "69f8f183-b057-4db5-8c87-3020168307c5", "loading": null } ...

Disabling functionality is not working properly when multiple expressions are added

One specific scenario involves using a radio button for selecting options and requiring users to confirm their selection using the JavaScript confirm method before enabling the next button. Take a look at the following code: HTML <body ng-controller ...

Centering the menu on the screen

I need help aligning the menu bar in the center. I have attempted to use text-align:center; but it is not working. You can view the website here. Any guidance would be appreciated. Thank you. <nav style="text-transform: uppercase;" id="site-navigation" ...

Sidenav Content with all elements having opacity applied

How can I ensure that all page elements have a black background color when the mobile navigation is opened on the left screen, while ensuring that my sidebar and content image do not get overlaid by the black background? Here is my code: function openNav( ...

Building a Div Tag Layout with CSS for Full Width and Left Position of 300px

Experiencing some trouble with styling a div element. My goal is to have the div start at left:300px and stretch across the entire width of the browser window. However, when I apply width:100%, the div extends beyond the boundaries of the browser screen. ...

In HTML, align the <p> element in the center between two floating <img> elements

Can someone explain why the code provided below is not centering the <p> text and instead placing it around 60-70% of the width? <div> <img src="logo.jpg" style="float: left;"> <p style="text-align: center;"> hello world </p&g ...

Initiating a SOAP WSDL request

Looking to create a Request for Comment (RFC) using a SAP function. A SAP data source was generated from this function. Upon visiting the following address: , a page with XML definitions is displayed. <?xml version="1.0" encoding="UTF-8&q ...

What is the technique for utilizing JavaScript to toggle the opening and closing of a Bootstrap 5 navbar dropdown?

My website is built using Bootstrap 5, and I am working on creating a navbar dropdown functionality. On desktop, I want the dropdown to open on hover and lead to a new page when clicked. However, on mobile, I only want the dropdown to open and close on cli ...

Tips for bringing in an npm package in JavaScript stimulus

Looking to utilize the imageToZ64() function within the zpl-image module. After installing it with: npm install zpl-image I attempted importing it using: import './../../../node_modules/zpl-image'; However, when trying to use the function like ...

Steps for resetting a previously selected row and highlighting a new row in JQGrid

I am facing an issue where I have row1 selected and highlighted, then when I select row2 it also gets highlighted. However, I want only row2 to be highlighted with CSS and row1 should go back to its default state or have the CSS removed. Can someone plea ...