最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Overflow scrolling not working on position fixed element iOS - Stack Overflow

programmeradmin3浏览0评论

I have position: fixed navigation bar at the very bottom of a page on mobile devices / sizes. The nav bar itself has an overflow container where the user can scroll to the right to see additional links (this is a design request and in my opinion a poor user experience, but that's my 2 cents).

The issue I've been seeing when testing on iOS devices is that the scrolling / any link clicking is not available when the top / bottom native browser elements are not on screen. In other words, when those elements auto-hide, the fixed behavior does not work at all. I've created a fiddle below and also included a snippet of the pertinent code under that, in case there's any issues viewing the fiddle on iOS properly:

Fiddle showing the behavior in question

.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=".11.1/jquery.min.js"></script>
<script src=".3.6/js/bootstrap.min.js"></script>
<link href=".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>

I have position: fixed navigation bar at the very bottom of a page on mobile devices / sizes. The nav bar itself has an overflow container where the user can scroll to the right to see additional links (this is a design request and in my opinion a poor user experience, but that's my 2 cents).

The issue I've been seeing when testing on iOS devices is that the scrolling / any link clicking is not available when the top / bottom native browser elements are not on screen. In other words, when those elements auto-hide, the fixed behavior does not work at all. I've created a fiddle below and also included a snippet of the pertinent code under that, in case there's any issues viewing the fiddle on iOS properly:

Fiddle showing the behavior in question

.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>

I've tried some alternative methods, such as -webkit-overflow-scrolling with no luck. I have a feeling this issue is unrelated. Seems to not even register that area of the screen without being pushed up by the native bottom bar on iOS.

Any and all assistance is much appreciated. Just running out of ideas to try on my own. I'm hoping to accomplish this with a minimum of JavaScript, but I'm not at all opposed. Thanks for your help!

Share Improve this question edited Jun 20, 2016 at 5:42 ghost_dad asked Jun 20, 2016 at 5:12 ghost_dadghost_dad 1,3062 gold badges12 silver badges21 bronze badges
Add a comment  | 

5 Answers 5

Reset to default 13

Taken from here.

When working with the overflow: scroll; attribute, the -webkit-overflow-scrolling: touch; attribute can be very useful on mobile sites. It basically changes the awkward scrolling behavior into the normal, expected behavior.

When you dynamically add content to a div with -webkit-overflow-scrolling: touch; that exceeds the div in height, it becomes broken and unscrollable. You can fix this by constantly having an inner div, that triggers the scrollbar because its 1px higher than the outer div:

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

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

I've not tested it.

On iOS, browsers (Safari, Chrome) are miscalculating content width that has been added dynamically after DOM load. For example, using pagination.js on a table didn't allow scrolling on mobile iOS devices. Solution is to add this css after changing content:

min-height:1000px

Alright, I was able to resolve the issue (which is kind of a weird one). For some reason, having the nav fixed to the very bottom seemed to be the issue. To fix this, I added additional space using the bottom property and added a pseudo-element to fill in the gap. Then, increased the height of the link elements inside the scroll container. Here's the updated code:

.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>

I've had the same issues as you when apple released iOS10. Your solution was what I needed! The footer in my app (made with meteor, running on iphone 7 with ios 10) was not sticking to the bottom. However I was able to solve it in a much shorter version.

On my footer div I put a class with position: fixed; and bottom: 0px; When doing bottom: 0; my footer is at the bottom of the content and not fixed.

I hope this helps other people with the same issue

This is what i did to solve the issue

Try to detect if the scrolling has stopped. Once the scrolling is stopped, then set the position:fixed on the header/footer.

  var scrollStop = function (callback) {
    // Make sure a valid callback was provided
    if (!callback || Object.prototype.toString.call(callback) !== '[object Function]') return;
    // Setup scrolling variable
    var isScrolling;
    // Listen for scroll events
    window.addEventListener('scroll', function (event) {
        // Clear our timeout throughout the scroll
        $("header").css("position","absolute");
        window.clearTimeout(isScrolling);
        // Set a timeout to run after scrolling ends
        isScrolling = setTimeout(function () {
            // Run the callback
            callback();
        }, 66);
    }, false);
};
// Example
scrollStop(function () {
    $("header").css("position","fixed");
    console.log("Swami scrolling has stopped");
});
发布评论

评论列表(0)

  1. 暂无评论