Position: Behoben funktioniert nicht auf iPad und iPhone

132

Ich habe eine Weile mit fester Positionierung im iPad zu kämpfen. Ich kenne iScroll und es scheint nicht immer zu funktionieren (selbst in ihrer Demo). Ich weiß auch, dass Sencha einen Fix dafür hat, aber ich konnte den Quellcode für diesen Fix nicht Ctrl+ F.

Ich hoffe, dass jemand die Lösung hat. Das Problem ist, dass fest positionierte Elemente nicht aktualisiert werden, wenn der Benutzer auf einer mobilen Safari mit iOS-Unterstützung nach unten / oben schwenkt.

Turm
quelle
2
Es sieht so aus, als ob jQuery Mobile 1.1 dieses Problem gelöst hat: jquerymobile.com/blog/2012/04/13/announcing-jquery-mobile-1-1-0
Tower
Mögliches Duplikat der festen Positionierung in Mobile Safari
Christian
Mögliches Duplikat mehrerer SO-Fragen. Weitere Informationen finden Sie unter gist.github.com/avesus/… .
Brian Haak

Antworten:

66

Viele mobile Browser unterstützen dies absichtlich nicht position:fixed;, da feste Elemente auf einem kleinen Bildschirm stören könnten.

Die Quirksmode.org-Website enthält einen sehr guten Blog-Beitrag, der das Problem erklärt: http://www.quirksmode.org/blog/archives/2010/12/the_fifth_posit.html

Auf dieser Seite finden Sie auch eine Kompatibilitätstabelle, die zeigt, welche mobilen Browser unterstützen position:fixed;: http://www.quirksmode.org/m/css.html

(Beachten Sie jedoch, dass sich die Welt der mobilen Browser sehr schnell bewegt, sodass Tabellen wie diese möglicherweise nicht lange auf dem neuesten Stand bleiben!)

Update: iOS 5 und Android 4 sollen beide Position haben: Unterstützung jetzt behoben.

Ich habe iOS 5 heute selbst in einem Apple Store getestet und kann bestätigen, dass es mit fester Position funktioniert. Es gibt jedoch Probleme beim Vergrößern und Schwenken eines festen Elements.

Ich fand diese Kompatibilitätstabelle weitaus aktueller und nützlicher als die im Quirksmode: http://caniuse.com/#search=fixed

Es verfügt über aktuelle Informationen zu Android, Opera (Mini und Mobile) und iOS.

Spudley
quelle
position:device-fixedwäre irgendwie überflüssig. position:fixedsollte nur nach W3C-Spezifikationen funktionieren.
Talvi Watia
@TalviWatia - die device-fixedLösung war nicht Teil meiner Antwort. Es kann als Vorschlag sinnvoll sein oder auch nicht, aber der Grund für den Link war eher die Erklärung des Problems als seine vorgeschlagene Lösung. Auf jeden Fall haben sich die Dinge seit der Veröffentlichung dieser Antwort sehr weiterentwickelt (wie ich bereits sagte), und viele neuere Geräte unterstützen dies fixed. Sie müssen sich jedoch immer noch mit älteren Geräten befassen, die dies nicht tun.
Spudley
54
Ich bin also gespannt, was genau Ihre Lösung für das vorliegende Problem ist. Die Links, die Sie möglicherweise hilfreich angegeben haben, lösen das vorliegende Problem nicht. Nicht abgestumpft zu sein, aber die Leute neigen dazu, Antworten zu bewerten, die hier auf SO eigentlich keine Antworten sind.
Talvi Watia
1
@TalviWatia: Als ich die Antwort schrieb, gab es keine wirklich gute Lösung für die Frage. Der Link, den ich gab, war die beste Diskussion, die ich kannte, um zu erklären, warum die Dinge so waren, wie sie waren, und die mangels einer Lösung so gut war, wie ich sie anbieten konnte. Die Dinge haben sich in der Zwischenzeit geändert, so dass die Diskussion im Link nicht mehr relevant ist und es jetzt Lösungen gibt, aber so war es damals.
Spudley
Eigentlich Position: Fest funktioniert für Skala 1, aber wenn der Benutzer das iPad zoomt, funktioniert es nicht in Ordnung. Position: Gerät fest vorhanden? Ist ein gültiges CSS-Attribut für Safari-iOS?
ccsakuweb
37

Die feste Positionierung funktioniert unter iOS nicht wie auf Computern.

Stellen Sie sich vor, Sie haben ein Blatt Papier (die Webseite) unter einer Lupe (dem Ansichtsfenster). Wenn Sie die Lupe und Ihr Auge bewegen, sehen Sie einen anderen Teil der Seite. So funktioniert iOS.

Jetzt gibt es eine durchsichtige Plastikfolie mit einem Wort darauf, diese Plastikfolie bleibt stationär, egal was passiert (die Position: feste Elemente). Wenn Sie also die Lupe bewegen, scheint sich das feste Element zu bewegen.

Anstatt die Lupe zu bewegen, bewegen Sie alternativ das Papier (die Webseite), wobei die Plastikfolie und die Lupe ruhig bleiben. In diesem Fall scheint das Wort auf der Plastikfolie fest zu bleiben, und der Rest des Inhalts scheint sich zu bewegen (weil es tatsächlich so ist). Dies ist ein traditioneller Desktop-Browser.

In iOS wird das Ansichtsfenster verschoben, in einem herkömmlichen Browser wird die Webseite verschoben. In beiden Fällen bleiben die festen Elemente in der Realität erhalten; obwohl unter iOS die festen Elemente sich zu bewegen scheinen.


Um dies zu umgehen, folgen Sie den letzten Absätzen in diesem Artikel

(Deaktivieren Sie das Scrollen im Grunde genommen vollständig, lassen Sie den Inhalt in einem separaten scrollbaren Div (siehe das blaue Feld oben im verlinkten Artikel) und das feste Element absolut positionieren.)


"position: fixed" funktioniert jetzt wie in iOS5 erwartet.

Jonathan.
quelle
Es gibt einige seltsame Dinge, die mit der Position passieren: behoben, wenn Sie auf IOS zoomen. Siehe stackoverflow.com/questions/52085998/…
Peter Hollingsworth
23

Position: Fest funktioniert auf Android / iPhone für vertikales Scrollen. Sie müssen jedoch sicherstellen, dass Ihre Meta-Tags vollständig festgelegt sind. z.B

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

Auch wenn Sie vorhaben, dass dieselbe Seite unter Android vor 4.0 funktioniert, müssen Sie auch die oberste Position festlegen, da sonst aus irgendeinem Grund ein kleiner Rand hinzugefügt wird.

Jason D.
quelle
Das hat bei mir tatsächlich funktioniert. Vorher hat Position: Fixiert auf einem versteckten Eingabeelement (siehe reine CSS-Navigation außerhalb des Bildschirms) dazu geführt, dass der Browser auf dem iPhone iOS 8.3, jedoch nicht auf dem Tablet abgestürzt ist. Nachdem es gut funktioniert.
Stephen Smith
Funktionierte nicht auf iPad iOS 10.3, horizontal in Square Stand. Zugegebener Autor sagt, dieser Ansatz sei für "Telefone".
SushiGuy
2
Wenn Sie das Zoomen des Benutzers deaktivieren, user-scalable=0, minimum-scale=1.0, maximum-scale=1.0kann die Seite für viele Benutzer weniger zugänglich sein. Es wäre nützlich, eine Warnung darüber in Ihre Antwort aufzunehmen
neiya
22

Jetzt unterstützt Apple das

overflow:hidden;
-webkit-overflow-scrolling:touch;
Uğur Özpınar
quelle
Das ist genau das, was ich nach meiner zu lösen background-size: coverund fixedAusgabe auf dem iPad
AndyB
Dies funktioniert unter Mobile Safari in iOS 7. Hinweis: Dies funktioniert nicht für Benutzer, die noch kein Upgrade auf diese Version durchgeführt haben.
Neil Monroe
Dann müssen noch einige andere Variablen am Werk sein. Ich habe auf iOS 6 getestet und es hat nicht funktioniert, dann auf iOS 7 und es war.
Neil Monroe
@ NeilMonroe hmm vielleicht. Ich bin mir sicher, dass ich es auf iOS 6 ohne Prob gemacht habe, aber vielleicht habe ich eine andere Variable verwendet. Ich erinnere mich nicht
Uğur Özpınar
Dies war wirklich hilfreich, aber es scheint, overflowmuss aufscroll
19

Ich hatte dieses Problem unter Safari (iOS 10.3.3) - der Browser wurde erst neu gezeichnet, als das Touchend-Ereignis ausgelöst wurde. Feste Elemente wurden nicht angezeigt oder wurden abgeschnitten.

Der Trick für mich war das Hinzufügen von transform: translate3d (0,0,0); zu meinem festen Positionselement.

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

BEARBEITEN - Ich weiß jetzt, warum die Transformation das Problem behebt: Hardwarebeschleunigung. Das Hinzufügen der 3D-Transformation löst die GPU-Beschleunigung aus und sorgt für einen reibungslosen Übergang. Weitere Informationen zur Hardwarebeschleunigung finden Sie in diesem Artikel: http://blog.teamtreehouse.com/increase-your-sites-performance-with-hardware-accelerated-css .

Kenecaswell
quelle
Dies hat tatsächlich mein Bildlaufproblem behoben, es wurde auf iOS-Geräten bei der Verwendung zurückgeworfen fixed, das hinzugefügt transformund dies wurde behoben.
vonUbisch
17

Feste Fußzeile (hier mit 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}

Ich hoffe es hilft.

Martin
quelle
7

Vermeiden Sie auf derselben Box mit transform: --- und position: fixed. Das Element bleibt in Position: statisch, wenn eine Transformation vorliegt.

Becario Senior
quelle
6

Am Ende habe ich das neue jQuery Mobile v1.1 verwendet: http://jquerymobile.com/blog/2012/04/13/announcing-jquery-mobile-1-1-0/

Wir haben jetzt ein solides Umschreiben, das echte feste Symbolleisten auf vielen gängigen Plattformen bietet und sicher auf die statische Positionierung der Symbolleiste in anderen Browsern zurückgreift.

Das Coolste an diesem Ansatz ist, dass sich unser Scrollen im Gegensatz zu JS-basierten Lösungen, die die unnatürliche Bildlaufphysik auf allen Plattformen auferlegen, zu 100% nativ anfühlt, weil es so ist . Dies bedeutet, dass sich das Scrollen überall richtig anfühlt und mit Benutzereingaben für Berührungen, Mausräder und Tastaturen funktioniert. Als Bonus ist unsere CSS-basierte Lösung sehr leicht und hat keinen Einfluss auf die Kompatibilität oder Zugänglichkeit.

Turm
quelle
Ebenfalls ziemlich elegant (aber definitiv eine Problemumgehung) ist diese Methode, um feste Objekte unter iOS ohne Verwendung von jQuery oder JavaScript zuzulassen (verwendet nur CSS). Es ist ziemlich universell einsetzbar. Wenn Sie möchten, dass ein "schwebendes" position:fixedElement vor Ihrer Bildlaufseite angezeigt wird, müssen Sie ihm nur einen höheren z-indexWert geben, damit es vorne bleibt.
Slink
Dies beantwortet die Frage definitiv nicht.
Gustavo Siqueira
1

Mit jquery kann ich mir das einfallen lassen. es rollt nicht glatt, aber es macht den Trick. Sie können nach unten scrollen und das feste Div wird oben angezeigt.

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

DER HTML

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

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

Schließlich möchten wir feststellen, ob sich der iPod im Quer- oder Hochformat berührt, um entsprechend angezeigt zu werden

<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>
Abdullah
quelle
1

Obwohl das CSS-Attribut {position:fixed;}(meistens) auf neueren iOS-Geräten zu funktionieren scheint, ist es möglich, dass das Gerät {position:relative;}gelegentlich und ohne Grund oder Grund auf etwas zurückgreift und zurückfällt . Normalerweise hilft es, den Cache zu leeren, bis etwas passiert und die Eigenart wieder passiert.

Insbesondere von Apple selbst Vorbereiten Ihres Webinhalts für das iPad :

Safari auf dem iPad und Safari auf dem iPhone haben keine Fenster mit veränderbarer Größe. In Safari auf iPhone und iPad wird die Fenstergröße auf die Größe des Bildschirms festgelegt (abzüglich der Steuerelemente der Safari-Benutzeroberfläche) und kann vom Benutzer nicht geändert werden. Um sich auf einer Webseite zu bewegen, ändert der Benutzer die Zoomstufe und Position des Ansichtsfensters, indem er zum Vergrößern oder Verkleinern zweimal tippt oder drückt oder durch Berühren und Ziehen die Seite schwenkt. Wenn ein Benutzer die Zoomstufe und Position des Ansichtsfensters ändert, geschieht dies innerhalb eines sichtbaren Inhaltsbereichs fester Größe (dh des Fensters). Dies bedeutet, dass Webseitenelemente, deren Position im Ansichtsfenster "festgelegt" ist, außerhalb des sichtbaren Inhaltsbereichs außerhalb des Bildschirms landen können.

Was ironisch ist, Android-Geräte scheinen dieses Problem nicht zu haben. Es ist auch durchaus möglich, {position:absolute;}in Bezug auf das Body-Tag zu verwenden und keine Probleme zu haben.

Ich fand die Grundursache für diese Eigenart; dass es sich um das Scroll-Ereignis handelt, das in Verbindung mit dem HTML- oder BODY-Tag nicht gut abgespielt wird. Manchmal wird das Ereignis nicht gerne ausgelöst, oder Sie müssen warten, bis das Scroll-Swing-Ereignis beendet ist, um das Ereignis zu empfangen. Insbesondere wird das Ansichtsfenster am Ende dieses Ereignisses neu gezeichnet, und feste Elemente können an einer anderen Stelle im Ansichtsfenster neu positioniert werden.

Das mache ich also: ( Vermeiden Sie die Verwendung des Ansichtsfensters und bleiben Sie beim 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>

Im Wesentlichen führt dies dazu, dass der KÖRPER die Größe des Ansichtsfensters hat und nicht scrollbar ist. Der im Inneren verschachtelte scrollbare DIV scrollt wie der KÖRPER normalerweise (abzüglich des Swing-Effekts, sodass das Scrollen am Touchend stoppt). Der feste DIV bleibt ohne Störung fixiert.

Als Randnotiz ist ein hoher z-indexWert für den festen DIV wichtig, damit der scrollbare DIV dahinter zu bleiben scheint. Normalerweise füge ich Ereignisse zur Größenänderung und zum Scrollen von Fenstern hinzu, um die Kompatibilität zwischen Browser und alternativer Bildschirmauflösung zu gewährleisten.

Wenn alles andere fehlschlägt, funktioniert der obige Code auch mit den festen und scrollbaren DIVs, die auf eingestellt sind {position:absolute;}.

Talvi Watia
quelle
1

Die einfache Möglichkeit, dieses Problem zu beheben, besteht darin, die Transformationseigenschaft für Ihr Element einzugeben. und es wird behoben. Viel Spaß beim Codieren :-)

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

Sie können auch seinen Weg versuchen, dies funktioniert auch gut.

.classname{
      position: -webkit-sticky;
    }
Amit Verma
quelle
0

Dies gilt möglicherweise nicht für alle Szenarien, aber ich habe festgestellt, dass position: sticky(dasselbe mit position: fixed) nur auf alten iPhones funktioniert, wenn sich der Bildlaufcontainer nicht im Körper befindet, sondern in etwas anderem.

Beispiel Pseudo-HTML:

body                         <- scrollbar
   relative div
       sticky div

Das Sticky Div wird in Desktop-Browsern klebrig sein, aber bei bestimmten Geräten, die getestet wurden mit: Chromium: dev tools: Geräteemultation: iPhone 6/7/8, und mit Android 4 Firefox nicht.

Was jedoch funktionieren wird, ist

body
    div overflow=auto       <- scrollbar
        relative div
            sticky div
phil294
quelle
0

In meinem Fall lag es daran, dass das feste Element mithilfe einer Animation angezeigt wurde. Wie in diesem Link angegeben :

Wenn in Safari 9.1 eine Position: festes Element in einem animierten Element vorhanden ist, wird die Position: festes Element möglicherweise nicht angezeigt.

nnimis
quelle
-2

Hier ist meine Lösung dafür ...

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>

Die Erklärung ist, dass die für das Div festgelegte Position das Div jederzeit im Hintergrund hält. Dann strecken wir das Div so, dass es mit (links, rechts, oben, unten) in alle Ecken des Browsers (vorausgesetzt, der Körperrand = 0) geht ) gleichzeitig.

Bitte stellen Sie sicher, dass Sie nicht die Breite und Höhe verwenden, da dies die Optionen oben, links, rechts und unten überschreibt.

Val
quelle