位置:固定在 iPad 和 iPhone 上不起作用

Posted

技术标签:

【中文标题】位置:固定在 iPad 和 iPhone 上不起作用【英文标题】:position: fixed doesn't work on iPad and iPhone 【发布时间】:2011-06-20 20:22:53 【问题描述】:

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

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

【问题讨论】:

看起来 jQuery Mobile 1.1 解决了这个问题:jquerymobile.com/blog/2012/04/13/announcing-jquery-mobile-1-1-0 Fixed positioning in Mobile Safari的可能重复 几个 SO 问题可能重复。详情请见gist.github.com/avesus/…。 【参考方案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 中正常工作了。

【讨论】:

在 IOS 上放大时 position:fixed 会发生一些奇怪的事情。见***.com/questions/52085998/…【参考方案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>

【讨论】:

以上是关于位置:固定在 iPad 和 iPhone 上不起作用的主要内容,如果未能解决你的问题,请参考以下文章

jQuery 显示和隐藏在 iPad 或 iPhone 上不起作用

jQuery 平滑滚动在 iPad 和 iPhone 上不起作用

CSS 跨浏览器问题 - 旋转在 Safari、Ipad 和 Iphone 上不起作用

jquery click 在 ipad/iphone 上不起作用

一些 javascript 函数在 iOS 设备(iPhone、iPad)上不起作用

iOS 内容拦截器在 iPad 上不起作用(在 iPhone 上很好)