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.


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


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.


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.


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;

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 .


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.


7

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


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.


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>

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;}.


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

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

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.


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

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.