【问题标题】:position: fixed doesn't work on iPad and iPhone位置:固定在 iPad 和 iPhone 上不起作用
【发布时间】:2023-03-05 15:11:01
【问题描述】:

一段时间以来,我一直在为 iPad 中的固定定位而苦苦挣扎。我知道iScroll,但它似乎并不总是有效(即使在他们的演示中)。我也知道 Sencha 对此有一个修复,但我无法 Ctrl + F 该修复的源代码。

我希望有人可以提供解决方案。问题是当用户在 iOS 驱动的移动 Safari 上向下/向上平移时,固定定位的元素不会得到更新。

【问题讨论】:

标签: iphone css ipad ios mobile


【解决方案1】:

很多移动浏览器故意不支持position:fixed;,理由是固定元素可能会妨碍小屏幕。

Quirksmode.org 网站有一篇很好的博文解释了这个问题:http://www.quirksmode.org/blog/archives/2010/12/the_fifth_posit.html

另请参阅此页面以获取显示哪些移动浏览器支持position:fixed;:http://www.quirksmode.org/m/css.html的兼容性图表

(但请注意,移动浏览器世界的发展速度非常快,因此此类表格可能不会长时间保持最新状态!)

更新: 据报道,iOS 5 和 Android 4 现在都具有 position:fixed 支持。

我今天在 Apple 商店亲自测试了 iOS 5,可以确认它确实可以在固定位置下工作。但是,放大和平移固定元素存在问题。

我发现这个兼容性表比 quirksmode 表更新和有用: http://caniuse.com/#search=fixed

它有关于 Android、Opera(迷你和移动)和 iOS 的最新信息。

【讨论】:

  • position:device-fixed 有点多余。 position:fixed 应该符合 W3C 规范。
  • @TalviWatia - device-fixed 解决方案不是我回答的一部分。它可能有也可能没有建议,但链接的原因是对问题的解释,而不是他建议的解决方案。无论如何,自从发布此答案(正如我所说的那样)以来,事情已经发生了很大变化,并且许多较新的设备确实支持fixed。不过,您仍然需要处理不需要的旧设备。
  • 所以我很好奇,您对手头问题的解决方案到底是什么?您提供的链接虽然可能有帮助,但并不能解决手头的问题。不要厌倦,但人们倾向于在 SO 上支持实际上不是答案的答案。
  • @TalviWatia:在我写答案的时候,这个问题并没有很好的解决方案。我提供的链接是我所知道的最好的讨论,可以解释 为什么 事情是这样的,在没有解决方案的情况下,这是我所能提供的。中间时期情况发生了变化,所以链接中的讨论不再相关,现在有解决方案,但当时就是这样。
  • 实际上位置:固定适用于比例 1,但当用户缩放 ipad 时,它不会正常工作。位置:设备固定存在?? safari ios 的 css 属性是否有效?
【解决方案2】:

固定定位在 iOS 上不像在计算机上那样工作。

假设您在放大镜(视口)下有一张纸(网页),如果您移动放大镜和眼睛,您会看到页面的不同部分。这就是 iOS 的工作原理。

现在有一张透明塑料片,上面有一个字,这片塑料片无论如何都保持静止(位置:固定元素)。因此,当您移动放大镜时,固定元素会出现移动。

或者,您不移动放大镜,而是移动纸张(网页),保持塑料片和放大镜不动。在这种情况下,塑料片上的文字看起来会保持固定,而其余内容会看起来会移动(因为它实际上是)这是一个传统的桌面浏览器。

因此,在 iOS 中,视口会移动,而在传统浏览器中,网页会移动。在这两种情况下,固定元素都保持在现实中;尽管在 iOS 上,固定元素似乎在移动。


解决这个问题的方法是遵循this article中的最后几段

(基本上完全禁用滚动,将内容放在单独的可滚动 div 中(参见链接文章顶部的蓝色框),并且固定元素绝对定位)


"position:fixed" 现在可以在 iOS5 中正常工作了。

【讨论】:

【解决方案3】:

position: fixed 在 android/iphone 上可以进行垂直滚动。但是您需要确保您的元标记已完全设置。例如

<meta name="viewport" content="width=device-width, height=device-height, initial-scale=1.0, user-scalable=0, minimum-scale=1.0, maximum-scale=1.0">

此外,如果您打算在 4.0 之前的 android 上使用相同的页面,您还需要设置顶部位置,否则会由于某种原因添加一个小边距。

【讨论】:

  • 这实际上对我有用。之前,位置:固定在隐藏的输入元素上(请参阅纯 css 屏幕外导航)导致浏览器在 iphone ios 8.3 上崩溃,但在平板电脑上没有。之后就可以正常工作了。
  • 不适用于 iPad iOS 10.3,在方形支架中水平放置。授权作者说这种方法适用于“手机”。
  • 使用user-scalable=0, minimum-scale=1.0, maximum-scale=1.0 禁止用户缩放会使许多用户无法访问该页面。在您的答案中添加有关它的警告会很有用
  • 谢谢,在 iPad Pro 12.9 上为我工作
【解决方案4】:

现在苹果支持了

overflow:hidden;
-webkit-overflow-scrolling:touch;

【讨论】:

  • 这正是我在 iPad 上解决 background-size: coverfixed 问题的目的
  • 这适用于 iOS 7 中的 Mobile Safari。注意:它不适用于尚未升级到此版本的用户。
  • 那么肯定还有其他一些变量在起作用。我在 iOS 6 上进行了测试,但它无法正常工作,然后在 iOS 7 上进行了测试。
  • @NeilMonroe 嗯,也许吧。我确定我已经在没有问题的情况下在 iOS 6 上完成了它,但也许我使用了其他变量。不记得了
  • 这确实很有帮助,但似乎 overflow 必须设置为 scroll
【解决方案5】:

使用 jquery 我能够想出这个。它滚动不流畅,但它确实有效。你可以向下滚动,固定的div会在顶部弹出。

CSS

<style type="text/css">
    .btn_cardDetailsPg {height:5px !important;margin-top:-20px;}
    html, body {overflow-x:hidden;overflow-y:auto;}
    #lockDiv {
  background-color: #fff;
  color: #000;
  float:left;
  -moz-box-shadow: 0px 4px 2px 2px #ccc;-webkit-box-shadow: 0px 4px 2px 2px #ccc;box-shadow:0px 4px 2px 2px #ccc;
  }
#lockDiv.stick {
  position: fixed;
  top: 0;
  z-index: 10000;
  margin-left:0px;
  }
</style>

HTML

<div id="lockSticky"></div>
<div id="lockDiv">fooo</div>

jquery

<script type="text/javascript">
    function sticky_relocate() {
        var window_top = $(window).scrollTop();
        var div_top = $('#lockSticky').offset().top;
        if (window_top > div_top)
            $('#lockDiv').addClass('stick')
        else
            $('#lockDiv').removeClass('stick');
    }
    $(function() {
        $(window).scroll(sticky_relocate);
        sticky_relocate();
    });
</script>

最后我们要确定ipod touch在横向还是纵向模式下是否相应显示

<script type="text/javascript">
    if (navigator.userAgent.match(/like Mac OS X/i)) {
        window.onscroll = function() {

        if (window.innerWidth > window.innerHeight) {
            //alert("landscape [ ]");
            document.getElementById('lockDiv').style.top =
            (window.pageYOffset + window.innerHeight - 268) + 'px';
        }

        if (window.innerHeight > window.innerWidth) {
            //alert("portrait ||");
            document.getElementById('lockDiv').style.top =
            (window.pageYOffset + window.innerHeight - 418) + 'px';
        }
        };
    }
</script>

【讨论】:

    【解决方案6】:

    我最终使用了新的 jQuery Mobile v1.1:http://jquerymobile.com/blog/2012/04/13/announcing-jquery-mobile-1-1-0/

    我们现在有一个可靠的重写,它在 许多流行的平台并安全地回退到静态工具栏 在其他浏览器中定位。

    这种方法最酷的地方在于,与基于 JS 的不同 将不自然的滚动物理强加于所有的解决方案 在平台上,我们的滚动感觉是 100% 原生的,因为它。这意味着 滚动感觉无处不在,并与触摸,鼠标滚轮一起工作 和键盘用户输入。作为奖励,我们基于 CSS 的解决方案非常棒 轻量级,不影响兼容性或可访问性。

    【讨论】:

    • this method 也非常优雅(但绝对是一种解决方法),它允许在 iOS 上固定对象而不使用 jQuery 或 JavaScript(仅使用 CSS)。它非常普遍适用。如果您希望“浮动”position:fixed 元素出现在滚动页面的前面,您只需要给它一个更高的 z-index 值,以便它保持在前面。
    • 这绝对不能回答问题。
    【解决方案7】:

    尽管 CSS 属性 {position:fixed;} 似乎(大部分)适用于较新的 iOS 设备,但有时可能会出现设备怪癖并回退到 {position:relative;},而没有任何原因或原因。通常清除缓存会有所帮助,直到发生某些事情并且怪癖再次发生。

    具体来说,来自苹果自己Preparing Your Web Content for iPad

    iPad 上的 Safari 和 iPhone 上的 Safari 没有可调整大小的窗口。在 iPhone 和 iPad 上的 Safari,窗口大小设置为 屏幕(减去 Safari 用户界面控件),并且无法更改 由用户。要在网页中移动,用户会更改缩放级别 和视口的位置,因为他们双击或捏放大或 或通过触摸和拖动来平移页面。随着用户的变化 他们正在执行的视口的缩放级别和位置 固定大小的可视内容区域(即窗口)。这意味着 将其位置“固定”到视口的网页元素 最终可能会出现在屏幕外的可视内容区域之外。

    具有讽刺意味的是,Android 设备似乎没有这个问题。此外,在引用 body 标签时完全可以使用{position:absolute;} 并且没有任何问题。

    我找到了这个怪癖的根本原因;与 HTML 或 BODY 标记结合使用时,滚动事件效果不佳。有时它不喜欢触发事件,或者您必须等到滚动摆动事件完成才能接收事件。具体来说,在此事件结束时重新绘制视口,并且可以将固定元素重新定位在视口中的其他位置。

    这就是我要做的:(避免使用视口,并坚持使用 DOM!

    <html>
      <style>
        .fixed{
          position:fixed;
          /*you can set your other static attributes here too*/
          /*like height and width, margin, etc.*/
          }
        .scrollableDiv{
          position:relative;
          overflow-y:scroll;
          /*all children will scroll within this like the body normally would.*/
          } 
        .viewportSizedBody{
          position:relative;
          overflow:hidden;
          /*this will prevent the body page itself from scrolling.*/
          } 
      </style>
      <body class="viewportSizedBody">
        <div id="myFixedContainer" class="fixed">
           This part is fixed.
        </div>
        <div id="myScrollableBody" class="scrollableDiv">
           This part is scrollable.
        </div>
      </body>
      <script type="text/javascript" src="{your path to jquery}/jquery-1.7.2.min.js"></script>
      <script>
        var theViewportHeight=$(window).height();
        $('.viewportSizedBody').css('height',theViewportHeight);
        $('#myScrollableBody').css('height',theViewportHeight);
      </script>
    </html>
    

    本质上,这将导致 BODY 成为视口的大小并且不可滚动。嵌套在里面的可滚动 DIV 会像 BODY 一样滚动(减去摇摆效果,所以滚动在 touchend 时会停止。)固定的 DIV 保持固定而不受干扰。

    附带说明,固定 DIV 上的高 z-index 值对于保持可滚动 DIV 显示在其后面很重要。我通常会添加窗口调整大小和滚动事件,以实现跨浏览器和备用屏幕分辨率的兼容性。

    如果所有其他方法都失败了,上面的代码也适用于设置为 {position:absolute;} 的固定和可滚动 DIV。

    【讨论】:

      【解决方案8】:

      固定页脚(这里使用 jQuery):

      if (navigator.platform == 'iPad' || navigator.platform == 'iPhone' || navigator.platform == 'iPod' || navigator.platform == 'Linux armv6l') 
      {
          window.ontouchstart = function () 
          {
              $("#fixedDiv").css("display", "none");
          }
      
          window.onscroll = function() 
          { 
              var iPadPosition = window.innerHeight + window.pageYOffset-45; // 45 is the height of the Footer
               $("#fixedDiv").css("position", "absolute");
               $("#fixedDiv").css("top", iPadPosition);
               $("#fixedDiv").css("display", "block");
          }
      }
      
      // in the CSS file should stand:
      #fixedDiv {position: fixed; bottom: 0; height: 45px;  whatever else}
      

      【讨论】:

        【解决方案9】:

        避免在同一个盒子上使用 transform:--- 和 position:fixed。如果有任何变换,元素将保持在 position:static 中。

        【讨论】:

          【解决方案10】:

          我在 Safari (iOS 10.3.3) 上遇到了这个问题 - 浏览器在触发 touchend 事件之前不会重绘。固定元素未出现或被截断。

          对我来说,诀窍是添加 transform: translate3d(0,0,0);到我的固定位置元素。

          .fixed-position-on-mobile {
            position: fixed;
            transform: translate3d(0,0,0);
          }
          

          编辑 - 我现在知道转换解决问题的原因:硬件加速。添加 3D 转换会触发 GPU 加速,从而实现平滑过渡。有关硬件加速检查的更多信息,请查看本文:http://blog.teamtreehouse.com/increase-your-sites-performance-with-hardware-accelerated-css

          【讨论】:

          • 这实际上解决了我的滚动问题,它在使用fixed 时在iOS 设备上弹跳,添加了transform 并已修复。
          【解决方案11】:

          解决此问题的简单方法是为您的元素键入 transform 属性。它将被修复。 。班级名称{ 位置:固定; 变换:translate3d(0,0,0); }

          你也可以试试他的方法,这也很好。

          .classname{
                position: -webkit-sticky;
              }
          

          【讨论】:

            【解决方案12】:

            这可能不适用于所有场景,但我发现position: sticky(与position: fixed 相同)仅适用于滚动容器不是主体的旧iPhone,而是在别的东西里面。

            伪html示例:

            body                         <- scrollbar
               relative div
                   sticky div
            

            粘性 div 会在桌面浏览器上具有粘性,但在某些设备上测试过:Chromium: dev tools: device emultation: iPhone 6/7/8,而在 Android 4 Firefox 上则不会。

            然而,可行的是

            body
                div overflow=auto       <- scrollbar
                    relative div
                        sticky div
            

            【讨论】:

              【解决方案13】:

              就我而言,这是因为使用动画显示了固定元素。如in this link所述:

              在 Safari 9.1 中,如果在动画元素中包含 position:fixed-element,可能会导致 position:fixed-element 不出现。

              【讨论】:

                【解决方案14】:

                在 Iphone X 上遇到了同样的问题。要修复它,我只需向容器添加高度

                top: 0;
                height: 200px;
                position: fixed;
                

                我刚刚添加了 top:0 因为我需要我的 div 保持在顶部

                【讨论】:

                  【解决方案15】:

                  这似乎适用于 iOS 12.4.2 上的 iphone 6 Plus 上的 Ionic5

                  .large_player {
                      float: left;
                        bottom: 0;
                        width: 100%;
                        position: fixed;
                        background-color: white;
                        border-top: black 1px solid;    
                        height: 14rem;
                        z-index: 100;
                        transform: translate3d(0,0,0);
                    }
                  

                  transform 标签使它工作,但它在滚动的工作方式上似乎有点笨拙,它似乎在它全部移动后重新绘制“顶部”元素并进行某种重置并使其跳跃一点.

                  或者,您也可以使用此标记选项,position: -webkit-sticky;,但是您不会得到,或者可能会遇到 WPA/浏览器或 Android 构建的问题,同时必须进行版本检查并拥有多个 CSS标签。

                  .large_player {
                      float: left;
                        bottom: 0;
                        width: 100%;
                        position: -webkit-sticky;
                        background-color: white;
                        border-top: black 1px solid;    
                        height: 14rem;
                        z-index: 100; 
                    }
                  

                  我不知道它是在什么时候修复的,但后来的 iOS 手机可以在没有转换标签的情况下工作。不知道是iOS版还是手机版。

                  由于大多数 iOS 设备通常都使用最新的 iOS 版本,因此使用一些奇怪的解决方法是相当安全的 - 例如使用transform 标签,而不是为了少于1% 的用户。

                  更新:

                  在进一步考虑这个答案后,这只是 ionic5+ 平台的另一种方式:

                  .TS

                  import {Platform } from '@ionic/angular';
                  
                  constructor(
                  public platform: Platform 
                  ) 
                  {  
                      // This next bit is so that the CSS is shown correctly for each platform    
                  
                      platform.ready().then(() => {
                      if (this.platform.is('android')) {
                          console.log("running on Android device!");
                          this.css_iOS = false;
                      }
                      if (this.platform.is('ios')) {
                          console.log("running on iOS device!");
                          this.css_iOS = true;
                      }     
                      if (this.platform.is('ipad')) {
                          console.log("running on iOS device!");
                          this.css_iOS = true;
                      }
                      });
                  }
                  css_iOS: boolean = false;
                  

                  .HTML

                  <style *ngIf="css_iOS">
                      .small_player {
                        position: -webkit-sticky !important;
                      }
                      .large_player {
                        position: -webkit-sticky !important;
                      }
                      </style>
                      
                      
                      <style>
                      .small_player {
                      float: left;
                        bottom: 0;
                        width: 100%;
                        position: fixed;
                        background-color: white;
                        border-top: black 1px solid;    
                        height: 4rem;
                        z-index: 100;
                        /*transform: translate3d(0,0,0);*/
                      }
                      
                      .large_player {
                      float: left;
                        bottom: 0;
                        width: 100%;
                        position: fixed;
                        background-color: white;
                        border-top: black 1px solid;    
                        height: 14rem;
                        z-index: 100;
                        /*transform: translate3d(0,0,0);*/
                      }
                      </style>
                  

                  【讨论】:

                    猜你喜欢
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 2011-03-25
                    • 2014-04-05
                    • 2018-11-26
                    • 1970-01-01
                    相关资源
                    最近更新 更多