position: fixed nie działa na iPadzie i iPhonie

135

Od jakiegoś czasu zmagam się ze stałym pozycjonowaniem w iPadzie. Znam iScroll i nie zawsze wydaje się działać (nawet w ich wersji demonstracyjnej). Wiem też, że Sencha ma na to poprawkę, ale nie mogłem Ctrl+ Fkodu źródłowego tej poprawki.

Mam nadzieję, że ktoś może mieć rozwiązanie. Problem polega na tym, że elementy o stałej pozycji nie są aktualizowane, gdy użytkownik przesuwa się w dół / w górę w mobilnej przeglądarce Safari z systemem iOS.

Wieża
źródło
2
Wygląda na to, że jQuery Mobile 1.1 rozwiązało ten problem: jquerymobile.com/blog/2012/04/13/announcing-jquery-mobile-1-1-0
Tower
możliwy duplikat Naprawiono pozycjonowanie w Mobile Safari
Christian
Możliwe powtórzenie kilku pytań SO. Szczegółowe informacje można znaleźć na stronie gist.github.com/avesus/… .
Brian Cannard

Odpowiedzi:

66

Wiele przeglądarek mobilnych celowo nie obsługuje position:fixed;tych urządzeń, ponieważ na małym ekranie mogą przeszkadzać stałe elementy.

Witryna Quirksmode.org zawiera bardzo dobry post na blogu, który wyjaśnia problem: http://www.quirksmode.org/blog/archives/2010/12/the_fifth_posit.html

Zobacz również tę stronę, aby zapoznać się z tabelą zgodności pokazującą obsługiwane przeglądarki mobilne position:fixed;: http://www.quirksmode.org/m/css.html

(ale pamiętaj, że świat przeglądarek mobilnych zmienia się bardzo szybko, więc takie tabele mogą nie pozostać aktualne przez długi czas!)

Aktualizacja: iOS 5 i Android 4 mają teraz pozycję: naprawiono wsparcie.

Samodzielnie przetestowałem iOS 5 w sklepie Apple i mogę potwierdzić, że działa z ustaloną pozycją. Występują jednak problemy z powiększaniem i przesuwaniem wokół stałego elementu.

Uważam, że ta tabela zgodności jest znacznie bardziej aktualna i użyteczna niż ta quirksmode: http://caniuse.com/#search=fixed

Zawiera aktualne informacje na temat Androida, Opery (mini i mobilnej) i iOS.

Spudley
źródło
position:device-fixedbyłoby trochę zbędne. position:fixedpowinien po prostu działać zgodnie ze specyfikacjami W3C.
Talvi Watia,
@TalviWatia - device-fixedrozwiązanie nie było częścią mojej odpowiedzi. Może mieć wartość, ale nie musi, jako sugestia, ale powodem umieszczenia odsyłacza było raczej wyjaśnienie problemu niż sugerowane przez niego rozwiązanie. W każdym razie od czasu opublikowania tej odpowiedzi wiele się zmieniło, a wiele nowszych urządzeń obsługuje fixed. Nadal jednak musisz radzić sobie ze starszymi urządzeniami, które tego nie robią.
Spudley,
55
Jestem więc ciekawy, jakie dokładnie jest Twoje rozwiązanie problemu? Linki, które podałeś, chociaż mogą być pomocne, nie rozwiązują problemu. Nie zblazować, ale ludzie mają tendencję do głosowania za odpowiedziami, które tak naprawdę nie są odpowiedziami tutaj na SO.
Talvi Watia
1
@TalviWatia: W czasie, gdy pisałem odpowiedź, nie było dobrego rozwiązania tego pytania. Link, który podałem, był najlepszą dyskusją, jaką znałem, aby wyjaśnić, dlaczego wszystko jest tak, jak jest, co w przypadku braku rozwiązania było tak dobre, jak mogłem zaoferować. W międzyczasie sytuacja się zmieniła, więc dyskusja w linku nie jest już aktualna i są teraz rozwiązania, ale tak było w tamtym czasie.
Spudley
Właściwie pozycja: ustalona działa dla skali 1, ale gdy użytkownik powiększa iPada, nie działa poprawnie. pozycja: urządzenie naprawione istnieje ?? Czy atrybut CSS jest prawidłowy dla Safari na iOS?
ccsakuweb
37

Stałe pozycjonowanie nie działa na iOS, tak jak na komputerach.

Wyobraź sobie, że masz kartkę papieru (stronę internetową) pod lupą (rzutnią), jeśli poruszysz lupą i okiem, zobaczysz inną część strony. Tak działa iOS.

Teraz jest arkusz przezroczystego plastiku z napisem, ten arkusz plastiku pozostaje nieruchomy bez względu na wszystko (pozycja: elementy stałe). Kiedy więc przesuwasz lupę, nieruchomy element wydaje się się poruszać.

Alternatywnie, zamiast przesuwać szkło powiększające, przesuwasz papier (stronę internetową), trzymając arkusz plastiku i szkło powiększające w bezruchu. W tym przypadku słowo na arkuszu plastiku będzie wyglądało na stałe, a reszta treści będzie się poruszać (ponieważ tak jest). To jest tradycyjna przeglądarka na komputer.

Tak więc w iOS porusza się okno ekranu, w tradycyjnej przeglądarce porusza się strona internetowa. W obu przypadkach stałe elementy pozostają w rzeczywistości; chociaż na iOS naprawione elementy wydają się poruszać.


Aby obejść ten problem, należy postępować zgodnie z kilkoma ostatnimi akapitami tego artykułu

(w zasadzie całkowicie wyłącz przewijanie, zawartość w osobnym przewijalnym div (zobacz niebieskie pole u góry połączonego artykułu), a stały element ustaw bezwzględnie)


„Position: fixed” działa teraz zgodnie z oczekiwaniami w iOS5.

Jonathan.
źródło
Jest kilka dziwnych rzeczy, które zdarzają się z pozycją: naprawione podczas powiększania w IOS. Zobacz stackoverflow.com/questions/52085998/…
Peter Hollingsworth
25

position: fixed działa na Androidzie / iPhonie do przewijania w pionie. Ale musisz się upewnić, że Twoje metatagi są w pełni ustawione. na przykład

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

Ponadto, jeśli planujesz mieć tę samą stronę na Androidzie w wersji wcześniejszej niż 4.0, musisz również ustawić najwyższą pozycję, w przeciwnym razie z jakiegoś powodu zostanie dodany mały margines.

Jason D.
źródło
To faktycznie zadziałało dla mnie. Wcześniej pozycja: naprawiona na ukrytym elemencie wejściowym (patrz czysta nawigacja css poza ekranem) powodowała awarię przeglądarki na telefonie iPhone ios 8.3, ale nie na tablecie. Po tym działa dobrze.
Stephen Smith
Nie działa na iPadzie iOS 10.3, poziomo w podstawce Square. Przyznany autor mówi, że to podejście jest dla „telefonów”.
SushiGuy,
2
Wyłączenie możliwości powiększenia przez użytkownika user-scalable=0, minimum-scale=1.0, maximum-scale=1.0może sprawić, że strona będzie mniej dostępna dla wielu użytkowników.
Przydałoby
22

teraz Apple to obsługuje

overflow:hidden;
-webkit-overflow-scrolling:touch;
Uğur Özpınar
źródło
To jest dokładnie to, co było po rozwiązać mój background-size: coverand fixedproblem na iPadzie
andyb
Działa to w przeglądarce Mobile Safari w iOS 7. Uwaga: nie będzie działać dla użytkowników, którzy nie dokonali jeszcze aktualizacji do tej wersji.
Neil Monroe,
W takim razie muszą działać inne zmienne. Testowałem na iOS 6 i nie działało, potem na iOS 7 i było.
Neil Monroe
@NeilMonroe hmm może. Jestem pewien, że zrobiłem to na iOS 6 bez problemu, ale może użyłem innej zmiennej. nie pamiętam
Uğur Özpınar
to było naprawdę pomocne, ale wydaje się, że overflowmusi być ustawione nascroll
20

Miałem ten problem na Safari (iOS 10.3.3) - przeglądarka nie przerysowywała aż do uruchomienia zdarzenia touchend. Naprawione elementy nie pojawiły się lub zostały odcięte.

Sztuczka polegała na dodaniu transform: translate3d (0,0,0); do mojego elementu o stałej pozycji.

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

EDYCJA - teraz wiem, dlaczego transformacja rozwiązuje problem: przyspieszenie sprzętowe. Dodanie transformacji 3D wyzwala przyspieszenie GPU, zapewniając płynne przejście. Więcej informacji na temat przyspieszania sprzętowego można znaleźć w tym artykule: http://blog.teamtreehouse.com/increase-your-sites-performance-with-hardware-accelerated-css .

kenecaswell
źródło
To faktycznie rozwiązało mój problem z przewijaniem, podskakiwał na urządzeniach z iOS podczas używania fixed, dodałem transformi zostało to naprawione.
vonUbisch,
17

Naprawiono stopkę (tutaj z 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}

Mam nadzieję, że to pomoże.

Jaskółka oknówka
źródło
7

Unikaj w tym samym pudełku za pomocą transform: --- i position: fixed. Element pozostanie na swoim miejscu: statyczny, jeśli jest jakakolwiek transformacja.

Becario Senior
źródło
6

Skończyło się na używaniu nowej wersji jQuery Mobile 1.1: http://jquerymobile.com/blog/2012/04/13/announcing-jquery-mobile-1-1-0/

Mamy teraz solidne przepisywanie, które zapewnia prawdziwe, stałe paski narzędzi na wielu popularnych platformach i bezpiecznie powraca do statycznego pozycjonowania pasków narzędzi w innych przeglądarkach.

Najfajniejsze w tym podejściu jest to, że w przeciwieństwie do rozwiązań opartych na JS, które narzucają nienaturalną fizykę przewijania na wszystkich platformach, nasze przewijanie jest w 100% natywne, ponieważ tak jest . Oznacza to, że przewijanie jest zawsze odpowiednie i działa za pomocą dotyku, kółka myszy i klawiatury. Dodatkowo, nasze rozwiązanie oparte na CSS jest super lekkie i nie wpływa na kompatybilność ani dostępność.

Wieża
źródło
Również dość elegancka (ale zdecydowanie obejście) jest ta metoda zezwalania na stałe obiekty w systemie iOS bez użycia jQuery lub JavaScript (używa tylko CSS). Ma uniwersalne zastosowanie. Jeśli chcesz, aby element „pływający” position:fixedpojawiał się przed przewijaną stroną, wystarczy, że nadasz mu wyższą z-indexwartość, aby pozostawał z przodu.
Slink
to zdecydowanie nie odpowiada na pytanie.
Gustavo Siqueira
1

używając jQuery jestem w stanie to wymyślić. nie przewija się płynnie, ale załatwia sprawę. możesz przewinąć w dół, a na górze pojawi się stały 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>

Na koniec chcemy ustalić, czy ipod touch ma być odpowiednio wyświetlany w trybie poziomym czy pionowym

<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
źródło
1

Mimo że atrybut CSS {position:fixed;}wydaje się (głównie) działać na nowszych urządzeniach z systemem iOS, możliwe jest, że urządzenie będzie dziwne i awaryjne {position:relative;}od czasu do czasu i bez przyczyny lub powodu. Zwykle wyczyszczenie pamięci podręcznej pomaga, dopóki coś się nie stanie i nie powtórzy się dziwactwo.

W szczególności od samego Apple przygotowującego treści internetowe na iPada :

Safari na iPadzie i Safari na iPhonie nie mają okien z możliwością zmiany rozmiaru. W Safari na iPhonie i iPadzie rozmiar okna jest ustawiony zgodnie z rozmiarem ekranu (bez elementów sterujących interfejsu użytkownika Safari) i użytkownik nie może go zmienić. Aby poruszać się po stronie internetowej, użytkownik zmienia poziom powiększenia i położenie rzutni, dotykając dwukrotnie lub szczypiąc, aby powiększyć lub pomniejszyć, lub dotykając i przeciągając, aby przesunąć stronę. Gdy użytkownik zmienia poziom powiększenia i położenie rzutni, robi to w widocznym obszarze zawartości o stałym rozmiarze (to jest w oknie). Oznacza to, że elementy strony internetowej, których pozycja jest „ustalona” w widoku, mogą znaleźć się poza widocznym obszarem zawartości, poza ekranem.

Co ironiczne, urządzenia z Androidem nie wydają się mieć tego problemu. Jest również całkowicie możliwe do użycia {position:absolute;}w odniesieniu do tagu body i nie ma żadnych problemów.

Znalazłem główną przyczynę tego dziwactwa; że jest to zdarzenie przewijania, które nie gra ładnie, gdy jest używane w połączeniu ze znacznikiem HTML lub BODY. Czasami nie lubi odpalać wydarzenia lub będziesz musiał poczekać, aż zdarzenie zamachu zwoju zostanie zakończone, aby odebrać wydarzenie. W szczególności rzutnia jest ponownie rysowana pod koniec tego zdarzenia, a stałe elementy można ponownie umieścić w innym miejscu w rzutni.

Oto, co robię: ( unikaj korzystania z widoku i trzymaj się 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>

W gruncie rzeczy spowoduje to, że BODY będzie miał rozmiar okna roboczego i nie będzie można go przewijać. Przewijalny DIV zagnieżdżony w środku będzie się przewijał jak normalnie BODY (bez efektu swing, więc przewijanie zatrzymuje się po dotknięciu). Ustalony DIV pozostaje stały bez zakłóceń.

Na marginesie, wysoka z-indexwartość ustalonego DIV jest ważna, aby przewijalny DIV wydawał się za nią. Zwykle dodaję zdarzenia zmiany rozmiaru i przewijania okna również w celu zapewnienia zgodności z różnymi przeglądarkami i alternatywnymi rozdzielczościami ekranu.

Jeśli wszystko inne zawiedzie, powyższy kod będzie również działał z ustawionymi i przewijalnymi DIV ustawionymi na {position:absolute;}.

Talvi Watia
źródło
1

Prostym sposobem rozwiązania tego problemu jest po prostu wpisanie właściwości transform dla elementu. i zostanie naprawiony. Miłego kodowania :-)

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

Możesz też spróbować jego sposobu, to również działa dobrze.

.classname{
      position: -webkit-sticky;
    }
Amit Verma
źródło
0

Może to nie mieć zastosowania do wszystkich scenariuszy, ale odkryłem, że position: sticky(to samo z position: fixed) działa tylko na starych iPhone'ach, gdy kontener przewijany nie jest ciałem, ale czymś innym.

Przykład pseudo html:

body                         <- scrollbar
   relative div
       sticky div

Przyklejony element div będzie się przyklejał w przeglądarkach na komputerach stacjonarnych, ale na niektórych urządzeniach przetestowany z: Chromium: narzędzia deweloperskie: emultacja urządzenia: iPhone 6/7/8, a na Androidzie 4 Firefox nie.

To jednak zadziała

body
    div overflow=auto       <- scrollbar
        relative div
            sticky div
phil294
źródło
0

W moim przypadku to dlatego, że stały element był pokazywany za pomocą animacji. Jak podano w tym linku :

w Safari 9.1 posiadanie pozycji: fixed-element wewnątrz animowanego elementu może spowodować, że pozycja: fixed-element nie pojawi się.

nnimis
źródło
0

Miałem ten sam problem na Iphone X. Aby go naprawić, dodaję tylko wysokość do pojemnika

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

Właśnie dodałem top: 0, ponieważ potrzebuję, aby mój div pozostał na górze

mpalencia
źródło
-2

oto moje rozwiązanie tego ...

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>

Wyjaśnienie jest takie, że ustalona pozycja elementu div będzie przez cały czas utrzymywać element div w tle, a następnie rozciągniemy go tak, aby znalazł się we wszystkich rogach przeglądarki (pod warunkiem, że margines treści = 0) za pomocą (lewy, prawy, górny, dolny ) równocześnie.

Upewnij się, że nie używasz szerokości i wysokości, ponieważ spowoduje to zastąpienie górnych, lewych, prawych i dolnych opcji.

Val
źródło