位置:固定不适用于iPad和iPhone

时间:2011-02-03 17:42:17

标签: iphone css ipad ios mobile

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

我希望有人可以解决这个问题。问题是,当用户在iOS移动的Safari上进行平移时,固定定位元素不会更新。

17 个答案:

答案 0 :(得分:65)

许多移动浏览器故意不支持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都有定位:现在支持固定。

我今天在Apple商店自己测试了iOS 5,并且可以确认它确实适用于固定位置。但是,在固定元素周围放大和平移存在问题。

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

它拥有Android,Opera(迷你和移动)和最新信息。的iOS。

答案 1 :(得分:37)

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

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

现在有一块透明塑料上面有一个字,这片塑料无论什么都固定不动(位置:固定元件)。因此,当您移动放大镜时,固定元素会出现以移动。

或者,不要移动放大镜,而是移动纸张(网页),保持塑料和放大镜片不动。在这种情况下,塑料薄片上的单词似乎保持固定,其余内容将显示为移动(因为它实际上是)这是一个传统的桌面浏览器。

因此在iOS中视口移动,在传统浏览器中移动网页。在这两种情况下,固定元素仍然存在;虽然在iOS上,固定元素似乎会移动。


解决这个问题的方法是遵循this article

中的最后几段

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


“position:fixed”现在可以像你在iOS5中所期望的那样工作。

答案 2 :(得分:22)

位置:固定可以在android / iphone上进行垂直滚动。但是您需要确保您的元标记已完全设置。 e.g

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

此外,如果您计划在android pre 4.0上使用相同的页面,您还需要设置顶部位置,或者由于某种原因会添加一小部分。

答案 3 :(得分:19)

现在苹果支持

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

答案 4 :(得分:14)

固定页脚(此处使用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}

希望它有所帮助。

答案 5 :(得分: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

答案 6 :(得分:7)

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

答案 7 :(得分:6)

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

  

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

     

这种方法最酷的部分是,与基于JS的不同   解决方案将不自然的滚动物理强加于所有人   平台,我们的滚动感觉100%原生,因为。这意味着   滚动感觉到处都是正确的,并且使用触摸,鼠标滚轮   和键盘用户输入。作为奖励,我们基于CSS的解决方案是超级的   轻量级,不影响兼容性或可访问性。

答案 8 :(得分:1)

使用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>

THE 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触摸是否相应显示

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

答案 9 :(得分:1)

尽管CSS属性{position:fixed;}似乎(大部分)都在较新的iOS设备上工作,但有时可能会让设备怪异并有时回退到{position:relative;}。通常清除缓存会有所帮助,直到出现问题并再次发生怪癖。

具体来说,来自Apple本身Preparing Your Web Content for iPad

  

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

具有讽刺意味的是,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。

答案 10 :(得分:0)

解决此问题的简单方法是为您的元素键入transform属性。它将被修复。快乐编码:-)

DOCUMENT_ROOT

您也可以尝试他的方式,这也很好。

.classname{
  position: fixed;
  transform: translate3d(0,0,0);
}

答案 11 :(得分:0)

这可能不适用于所有情况,但我发现position: sticky(与position: fixed相同)仅在滚动容器为不是的情况下才可在旧版iPhone上使用。身体,但在其他内部。

伪HTML示例:

body                         <- scrollbar
   relative div
       sticky div

sticky div将在桌面浏览器上保持粘性,但在某些设备上进行了以下测试:Chromium:开发工具:设备兼容:iPhone 6/7/8,而对于Android 4 Firefox,则不会。

但是有效的是

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

答案 12 :(得分:0)

在我的情况下,这是因为固定元素是通过使用动画来显示的。如in this link所述:

在Safari 9.1中,动画元素中具有position:fixed-element,可能会导致position:fixed-element不出现。

答案 13 :(得分:0)

在Iphone X上也有同样的问题。要修复它,我只是在容器上增加了高度

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

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

答案 14 :(得分:0)

这似乎适用于 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>

答案 15 :(得分:-1)

在我的例子中,滚动显示了添加到DOM时最初未显示的position: fixed元素。所以我只是手动触发了滚动事件,而事件又触发了重绘和瞧瞧。

window.scrollTo(window.scrollX, window.scrollY);

答案 16 :(得分:-2)

这是我对此的解决方案......

CSS

#bgimg_top {
    background: url(images/bg.jpg) no-repeat 50% 0%; 
    position: fixed; 
    top:0; 
    left: 0; 
    right:0 ; 
    bottom:0;
}

<强> HTML

<body>
<div id="bgimg_top"></div>
....
</body>

说明为div固定的位置将div始终保持在背景上,然后我们将div拉伸到浏览器的所有角落(假设身体边距= 0),使用(左,右,顶部,底部)同时。

请确保您不使用宽度和高度,因为这将覆盖顶部,左侧,右侧,底部选项。