position: fixed não funciona no iPad e iPhone

132

Estou lutando com o posicionamento fixo no iPad há um tempo. Eu conheço o iScroll e nem sempre parece funcionar (mesmo em sua demonstração). Sei também que o Sencha tem uma correção para isso, mas não consegui Ctrl+ Fo código fonte dessa correção.

Espero que alguém possa ter a solução. O problema é que os elementos de posição fixa não são atualizados quando o usuário faz um down / up em um Safari móvel com iOS.

Torre
fonte
2
Parece que o jQuery Mobile 1.1 resolveu este problema: jquerymobile.com/blog/2012/04/13/announcing-jquery-mobile-1-1-0
Tower
possível duplicata de posicionamento fixo no Mobile Safari
Christian
Possível duplicação de várias questões SO. Veja gist.github.com/avesus/… para detalhes.
Brian Haak

Respostas:

66

Muitos navegadores móveis deliberadamente não suportam position:fixed; o argumento de que elementos fixos podem atrapalhar em uma tela pequena.

O site Quirksmode.org tem uma publicação muito boa no blog que explica o problema: http://www.quirksmode.org/blog/archives/2010/12/the_fifth_posit.html

Consulte também esta página para obter um gráfico de compatibilidade mostrando quais navegadores móveis suportam position:fixed;: http://www.quirksmode.org/m/css.html

(mas observe que o mundo dos navegadores móveis está se movendo muito rapidamente, portanto, tabelas como essa podem não ficar atualizadas por muito tempo!)

Atualização: iOS 5 e Android 4 são relatados como tendo posição: suporte fixo agora.

Hoje eu testei o iOS 5 em uma loja da Apple e posso confirmar que ele funciona com a posição fixa. Existem problemas com o zoom e o panorama em torno de um elemento fixo.

Achei essa tabela de compatibilidade muito mais atualizada e útil que a do quirksmode: http://caniuse.com/#search=fixed

Possui informações atualizadas no Android, Opera (mini e celular) e iOS.

Spudley
fonte
position:device-fixedseria meio redundante. position:fixeddeve funcionar apenas com as especificações do W3C.
precisa saber é o seguinte
@TalviWatia - a device-fixedsolução não fazia parte da minha resposta. Pode ou não ter mérito como sugestão, mas o motivo do link foi a explicação do problema, e não a solução sugerida. De qualquer forma, as coisas mudaram bastante desde que essa resposta foi postada (como eu disse) e muitos dispositivos mais novos são compatíveis fixed. Você ainda precisa lidar com dispositivos mais antigos que não o fazem.
Spudley
54
Estou curioso, qual é exatamente a sua solução para o problema em questão? Os links que você forneceu enquanto possivelmente úteis não resolvem o problema em questão. Não deve ser cansada, mas as pessoas tendem a votar de forma mais positiva que não são respostas aqui no SO.
precisa saber é o seguinte
1
@TalviWatia: No momento em que escrevi a resposta, não havia realmente uma boa solução para a pergunta. O link que dei foi a melhor discussão que conheci para explicar por que as coisas eram do jeito que eram, o que, na ausência de uma solução, era tão bom quanto eu poderia oferecer. As coisas mudaram no período intermediário; portanto, a discussão no link não é mais relevante, e existem soluções agora, mas era assim na época.
Spudley
Na verdade, posição: trabalhos fixos para a escala 1, mas quando o usuário faz zoom no ipad, ele não funciona. posição: dispositivo fixo existe ?? O atributo css é válido para o safari ios?
precisa saber é o seguinte
37

O posicionamento fixo não funciona no iOS, como nos computadores.

Imagine que você tem uma folha de papel (a página da Web) sob uma lente de aumento (a janela de visualização); se você mover a lente de aumento e seus olhos, verá uma parte diferente da página. É assim que o iOS funciona.

Agora há uma folha de plástico transparente com uma palavra, esta folha de plástico permanece estacionária, não importa qual seja (a posição: elementos fixos). Então, quando você move a lupa, o elemento fixo parece se mover.

Como alternativa, em vez de mover a lupa, mova o papel (a página da web), mantendo a folha de plástico e a lupa imóvel. Nesse caso, a palavra na folha de plástico parecerá permanecer fixa e o restante do conteúdo parecerá mover-se (porque realmente é). Este é um navegador de desktop tradicional.

Assim, no iOS, a viewport se move; em um navegador tradicional, a página da web se move. Nos dois casos, os elementos fixos permanecem imóveis na realidade; embora no iOS os elementos fixos pareçam se mover.


A maneira de contornar isso é seguir os últimos parágrafos deste artigo

(basicamente desative a rolagem por completo, tenha o conteúdo em uma div rolável separada (veja a caixa azul na parte superior do artigo vinculado) e o elemento fixo posicionado absolutamente)


"position: fixed" agora funciona como seria de esperar no iOS5.

Jonathan.
fonte
Há algumas coisas estranhas que acontecem com a posição: corrigidas quando você aumenta o zoom no IOS. Veja stackoverflow.com/questions/52085998/…
Peter Hollingsworth
23

position: fixed funciona no android / iphone para rolagem vertical. Mas você precisa garantir que suas metatags estejam totalmente definidas. por exemplo

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

Além disso, se você planeja ter a mesma página funcionando no Android 4.0, você também precisa definir a posição superior, ou uma pequena margem será adicionada por algum motivo.

Jason D.
fonte
Isso realmente funcionou para mim. Antes, a posição: fixada em um elemento de entrada oculto (consulte a navegação css fora da tela) fazia com que o navegador travasse no iphone ios 8.3, mas não no tablet. Depois que funciona bem.
Stephen Smith
Não funcionou no iPad iOS 10.3, horizontal no suporte quadrado. O autor concedido diz que essa abordagem é para "telefones".
precisa saber é o seguinte
2
Desabilitar o zoom do usuário user-scalable=0, minimum-scale=1.0, maximum-scale=1.0pode tornar a página menos acessível para muitos usuários. Seria útil para adicionar um aviso sobre isso em sua resposta
neiya
22

agora suporte a apple que

overflow:hidden;
-webkit-overflow-scrolling:touch;
Uğur Özpınar
fonte
Este é exatamente o que eu estava depois de resolver o meu background-size: covere fixededição no iPad
andyb
Isso funciona no Mobile Safari no iOS 7. Nota: Ele não funcionará para usuários que ainda não fizeram o upgrade para esta versão.
Neil Monroe
Então deve haver algumas outras variáveis ​​no trabalho. Eu testei no iOS 6 e ele não estava funcionando, então no iOS 7 e estava.
Neil Monroe
@NeilMonroe hmm talvez. Tenho certeza de que fiz no iOS 6 sem problemas, mas talvez eu tenha usado outra variável. não lembro
Uğur Özpınar
este foi realmente útil, mas ao que parece, overflowtem de ser definido parascroll
19

Eu tive esse problema no Safari (iOS 10.3.3) - o navegador não foi redesenhado até que o evento do touchend fosse disparado. Os elementos fixos não apareceram ou foram cortados.

O truque para mim foi adicionar transform: translate3d (0,0,0); ao meu elemento de posição fixa.

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

EDIT - Agora eu sei por que a transformação corrige o problema: aceleração de hardware. A adição da transformação 3D aciona a aceleração da GPU, facilitando a transição. Para obter mais informações sobre a aceleração de hardware, consulte este artigo: http://blog.teamtreehouse.com/increase-your-sites-performance-with-hardware-accelerated-css .

Kenecaswell
fonte
Na verdade, isso corrigiu meu problema de rolagem; ele estava saltando nos dispositivos iOS ao usar fixed, adicionou o transforme isso foi corrigido.
vonUbisch 16/08/19
17

Rodapé fixo (aqui com 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}

Espero que ajude.

Martin
fonte
7

Evite na mesma caixa usando transform: --- e position: fixed. O elemento permanecerá na posição: estático se houver alguma transformação.

Becario Senior
fonte
6

Acabei usando o novo jQuery Mobile v1.1: http://jquerymobile.com/blog/2012/04/13/announcing-jquery-mobile-1-1-0/

Agora, temos uma reescrita sólida que fornece verdadeiras barras de ferramentas fixas em muitas plataformas populares e volta com segurança ao posicionamento estático da barra de ferramentas em outros navegadores.

A parte mais legal dessa abordagem é que, diferentemente das soluções baseadas em JS que impõem a física de rolagem não natural em todas as plataformas, nossa rolagem parece 100% nativa porque é . Isso significa que a rolagem parece certa em todos os lugares e funciona com a entrada do usuário por toque, roda do mouse e teclado. Como bônus, nossa solução baseada em CSS é super leve e não afeta a compatibilidade ou acessibilidade.

Torre
fonte
Também bastante elegante (mas definitivamente uma solução alternativa) é esse método para permitir objetos fixos no iOS sem usar jQuery ou JavaScript (usa apenas CSS). É universalmente aplicável. Se você deseja que um position:fixedelemento "flutuante" apareça na frente da sua página de rolagem, basta atribuir um z-indexvalor mais alto para que fique na frente.
Slink
isso definitivamente não responde à pergunta.
Gustavo Siqueira
1

Usando jquery eu sou capaz de chegar a isso. ele não rola suavemente, mas faz o truque. você pode rolar para baixo e a div fixa aparece na parte superior.

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

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

Finalmente, queremos determinar se o ipod touch no modo paisagem ou retrato será exibido adequadamente

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

Embora o atributo CSS {position:fixed;}pareça (na maioria das vezes) funcionar em dispositivos iOS mais novos, é possível fazer com que o dispositivo funcione de vez {position:relative;}em quando e sem motivo ou motivo. Normalmente, limpar o cache ajudará, até que algo aconteça e a peculiaridade aconteça novamente.

Especificamente, da própria Apple Preparando o conteúdo da Web para iPad :

O Safari no iPad e o Safari no iPhone não têm janelas redimensionáveis. No Safari no iPhone e iPad, o tamanho da janela é definido como o tamanho da tela (menos os controles da interface do usuário do Safari) e não pode ser alterado pelo usuário. Para mover-se por uma página da Web, o usuário altera o nível de zoom e a posição da janela de visualização ao tocar duas vezes ou beliscar para aumentar ou diminuir o zoom ou tocar e arrastar para deslocar a página. À medida que o usuário altera o nível de zoom e a posição da viewport, ele o faz em uma área de conteúdo visível de tamanho fixo (ou seja, a janela). Isso significa que os elementos da página da Web que têm sua posição "fixa" na janela de exibição podem acabar fora da área de conteúdo visível, fora da tela.

O que é irônico, os dispositivos Android não parecem ter esse problema. Além disso, é totalmente possível usá-lo {position:absolute;}quando em referência à etiqueta do corpo e não apresentar nenhum problema.

Eu encontrei a causa raiz dessa peculiaridade; que o evento de rolagem não está funcionando bem quando usado em conjunto com a tag HTML ou BODY. Às vezes, ele não gosta de disparar o evento ou você terá que esperar até que o evento de balanço de rolagem termine para receber o evento. Especificamente, a viewport é redesenhada no final deste evento e elementos fixos podem ser reposicionados em outro lugar na viewport.

Então é isso que eu faço: ( evite usar a viewport e fique com o 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>

Em essência, isso fará com que o BODY seja do tamanho da viewport e não seja rolável. O DIV rolável aninhado no interior rolará como o BODY normalmente faria (menos o efeito de balanço, para que a rolagem pare no toque). O DIV fixo permanece fixo sem interferência.

Como observação lateral, z-indexé importante um alto valor no DIV fixo para manter o DIV rolável atrás dele. Normalmente, eu adiciono o redimensionamento de janelas e os eventos de rolagem também para compatibilidade entre navegadores e resolução de tela alternativa.

Se tudo mais falhar, o código acima também funcionará com os DIVs fixos e roláveis ​​configurados como {position:absolute;}.

Talvi Watia
fonte
1

A maneira simples de corrigir esse problema apenas digita a propriedade transform do seu elemento. e será corrigido. Happy Coding :-)

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

Além disso, você pode tentar o seu caminho, assim também é um bom trabalho.

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

Isso pode não ser aplicável a todos os cenários, mas eu descobri que a position: stickymesma coisa position: fixedsó funciona em iPhones antigos quando o contêiner de rolagem não é o corpo, mas dentro de outra coisa.

Exemplo de pseudo html:

body                         <- scrollbar
   relative div
       sticky div

A div pegajosa será pegajosa nos navegadores da área de trabalho, mas em certos dispositivos testados com: Chromium: dev tools: emultação de dispositivo: iPhone 6/7/8 e no Android 4 Firefox, não.

O que vai funcionar, no entanto, é

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

No meu caso, foi porque o elemento fixo estava sendo mostrado usando uma animação. Conforme declarado neste link :

no Safari 9.1, com a posição: elemento fixo dentro de um elemento animado, pode fazer com que a posição: elemento fixo não apareça.

nnimis
fonte
-2

aqui está a minha solução para isso ...

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>

A explicação é que a posição fixada para a div manterá a div em segundo plano o tempo todo; depois, esticamos a div para ir em todos os cantos do navegador (desde que a margem do corpo = 0) use o botão (esquerdo, direito, superior, inferior) ) simultaneamente.

Certifique-se de não usar a largura e a altura, pois isso substituirá as opções superior, esquerda, direita e inferior.

Val
fonte