posición: fijo no funciona en iPad y iPhone

132

He estado luchando con el posicionamiento fijo en iPad por un tiempo. Conozco iScroll y no siempre parece funcionar (incluso en su demo). También sé que Sencha tiene una solución para eso, pero no pude Ctrl+ Fel código fuente de esa solución.

Espero que alguien pueda tener la solución. El problema es que los elementos de posición fija no se actualizan cuando el usuario desplaza hacia abajo / arriba en un Safari móvil con iOS.

Torre
fuente
2
Parece que jQuery Mobile 1.1 resolvió este problema: jquerymobile.com/blog/2012/04/13/announcing-jquery-mobile-1-1-0
Tower
posible duplicado de posicionamiento fijo en Mobile Safari
Christian
Posible duplicado de varias preguntas SO. Visite gist.github.com/avesus/… para más detalles.
Brian Haak

Respuestas:

66

Muchos navegadores móviles deliberadamente no son compatibles position:fixed;porque los elementos fijos pueden interferir en una pantalla pequeña.

El sitio Quirksmode.org tiene una muy buena publicación de blog que explica el problema: http://www.quirksmode.org/blog/archives/2010/12/the_fifth_posit.html

Consulte también esta página para ver un cuadro de compatibilidad que muestra qué navegadores móviles son compatibles position:fixed;: http://www.quirksmode.org/m/css.html

(¡pero tenga en cuenta que el mundo del navegador móvil se está moviendo muy rápidamente, por lo que las tablas como esta pueden no estar actualizadas por mucho tiempo!)

Actualización: se informa que iOS 5 y Android 4 tienen posición: soporte fijo ahora.

Probé iOS 5 en una tienda de Apple hoy y puedo confirmar que funciona con la posición fija. Sin embargo, hay problemas con el acercamiento y el desplazamiento alrededor de un elemento fijo.

Encontré esta tabla de compatibilidad mucho más actualizada y útil que la del modo peculiar: http://caniuse.com/#search=fixed

Tiene información actualizada sobre Android, Opera (mini y móvil) e iOS.

Spudley
fuente
position:device-fixedSería algo redundante. position:fixeddebería funcionar según las especificaciones del W3C.
Talvi Watia
@TalviWatia: la device-fixedsolución no fue parte de mi respuesta. Puede o no tener mérito como sugerencia, pero la razón del enlace fue la explicación del problema en lugar de su solución sugerida. En cualquier caso, las cosas han avanzado mucho desde que se publicó esta respuesta (como dije), y muchos dispositivos más nuevos son compatibles fixed. Sin embargo, aún debe lidiar con dispositivos más antiguos que no lo hacen.
Spudley
54
Así que tengo curiosidad, ¿cuál es exactamente su solución al problema en cuestión? Los enlaces que proporcionó, aunque posiblemente útiles, no resuelven el problema en cuestión. No es para cansarse, pero la gente tiende a votar las respuestas que en realidad no son respuestas aquí en SO.
Talvi Watia
1
@TalviWatia: En el momento en que escribí la respuesta, no había una buena solución para la pregunta. El enlace que di fue la mejor discusión que conocí para explicar por qué las cosas eran como eran, lo que en ausencia de una solución fue tan bueno como pude ofrecer. Las cosas han cambiado en el período intermedio, por lo que la discusión en el enlace ya no es relevante, y ahora hay soluciones, pero así era en ese momento.
Spudley
En realidad, la posición: fija funciona para la escala 1, pero cuando el usuario hace zoom en el ipad, no funcionará bien. posición: ¿existe un dispositivo fijo? ¿Es válido el atributo CSS para Safari IOS?
ccsakuweb
37

El posicionamiento fijo no funciona en iOS como lo hace en las computadoras.

Imagine que tiene una hoja de papel (la página web) debajo de una lupa (la ventana), si mueve la lupa y su ojo, verá una parte diferente de la página. Así es como funciona iOS.

Ahora hay una lámina de plástico transparente con una palabra, esta lámina de plástico permanece estacionaria pase lo que pase (la posición: elementos fijos). Entonces, cuando mueve la lupa, el elemento fijo parece moverse.

Alternativamente, en lugar de mover la lupa, mueves el papel (la página web), manteniendo la hoja de plástico y la lupa inmóviles. En este caso, la palabra en la lámina de plástico parecerá estar fija, y el resto del contenido parecerá moverse (porque en realidad lo es). Este es un navegador de escritorio tradicional.

Entonces, en iOS, la ventana gráfica se mueve, en un navegador tradicional se mueve la página web. En ambos casos, los elementos fijos permanecen inmóviles en la realidad; aunque en iOS los elementos fijos parecen moverse.


La forma de evitar esto es seguir los últimos párrafos de este artículo.

(básicamente deshabilite el desplazamiento por completo, tenga el contenido en un div desplazable separado (vea el cuadro azul en la parte superior del artículo vinculado), y el elemento fijo posicionado absolutamente)


"position: fixed" ahora funciona como cabría esperar en iOS5.

Jonathan
fuente
Hay algunas cosas extrañas que suceden con la posición: fija cuando se acerca el IOS Ver stackoverflow.com/questions/52085998/…
Peter Hollingsworth
23

position: fixed funciona en android / iphone para desplazamiento vertical. Pero debe asegurarse de que sus metaetiquetas estén completamente configuradas. p.ej

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

Además, si planea que la misma página funcione en Android pre 4.0, también debe establecer la posición superior, o se agregará un pequeño margen por algún motivo.

Jason D.
fuente
Esto realmente funcionó para mí. Antes, la posición: fijada en un elemento de entrada oculto (ver CSS puro fuera de la pantalla de navegación) hizo que el navegador se bloqueara en el iPhone iOS 8.3 pero no en la tableta. Después de que funciona bien.
Stephen Smith
No funcionó en iPad iOS 10.3, horizontal en soporte cuadrado. Autor autorizado dice que este enfoque es para "teléfonos".
SushiGuy
2
Deshabilitar el zoom del usuario user-scalable=0, minimum-scale=1.0, maximum-scale=1.0puede hacer que la página sea menos accesible para muchos usuarios. Sería útil agregar una advertencia al respecto en su respuesta
neiya
22

ahora Apple apoya eso

overflow:hidden;
-webkit-overflow-scrolling:touch;
Uğur Özpınar
fuente
Esto es exactamente lo que yo buscaba a resolver mi background-size: covery fixedtema en el IPAD
andyb
Esto funciona en Mobile Safari en iOS 7. Nota: no funcionará para los usuarios que aún no hayan actualizado a esta versión.
Neil Monroe
Entonces debe haber algunas otras variables en el trabajo. He probado en iOS 6 y no funcionaba, luego en iOS 7 y lo estaba.
Neil Monroe
@NeilMonroe hmm tal vez. Estoy seguro de que lo hice en iOS 6 sin problemas, pero tal vez utilicé otra variable. no recuerdo
Uğur Özpınar
esto fue realmente útil, pero parece que overflowtiene que configurarse enscroll
19

Tuve este problema en Safari (iOS 10.3.3): el navegador no se redibujó hasta que se desencadenó el evento touchend. Los elementos fijos no aparecieron o se cortaron.

El truco para mí fue agregar transform: translate3d (0,0,0); a mi elemento de posición fija.

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

EDITAR : ahora sé por qué la transformación soluciona el problema: aceleración de hardware. Agregar la transformación 3D desencadena la aceleración de la GPU para una transición suave. Para obtener más información sobre la aceleración de hardware, consulte este artículo: http://blog.teamtreehouse.com/increase-your-sites-performance-with-hardware-accelerated-css .

kenecaswell
fuente
Esto realmente solucionó mi problema de desplazamiento, rebotaba en dispositivos iOS cuando lo usaba fixed, agregaba transformy esto se solucionó.
vonUbisch
17

Pie de página fijo (aquí con 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 eso ayude.

Martín
fuente
7

Evite en el mismo cuadro usando transform: --- y position: fixed. El elemento permanecerá en posición: estático si hay alguna transformación.

Becario Senior
fuente
6

Terminé usando el nuevo jQuery Mobile v1.1: http://jquerymobile.com/blog/2012/04/13/announcing-jquery-mobile-1-1-0/

Ahora tenemos una reescritura sólida que proporciona verdaderas barras de herramientas fijas en muchas plataformas populares y vuelve a caer de forma segura al posicionamiento estático de la barra de herramientas en otros navegadores.

La mejor parte de este enfoque es que, a diferencia de las soluciones basadas en JS que imponen la física de desplazamiento no natural en todas las plataformas, nuestro desplazamiento se siente 100% nativo porque lo es . Esto significa que el desplazamiento se siente en todas partes y funciona con la entrada del usuario táctil, de la rueda del mouse y del teclado. Como beneficio adicional, nuestra solución basada en CSS es súper liviana y no afecta la compatibilidad o accesibilidad.

Torre
fuente
También es bastante elegante (pero definitivamente una solución) este método para permitir objetos fijos en iOS sin usar jQuery o JavaScript (solo usa CSS). Es bastante universalmente aplicable. Si desea position:fixedque aparezca un elemento "flotante" delante de su página de desplazamiento, solo necesita darle un z-indexvalor más alto para que permanezca delante.
Slink
Esto definitivamente no responde la pregunta.
Gustavo Siqueira
1

usando jquery puedo llegar a esto. no se desplaza suavemente, pero hace el truco. puede desplazarse hacia abajo y el div fijo aparece en la parte superior.

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

EL HTML

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

LA 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 si el iPod touch en modo horizontal o vertical se mostrará en consecuencia

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

A pesar de que el atributo CSS {position:fixed;}parece (principalmente) funcionar en dispositivos iOS más nuevos, es posible tener el dispositivo peculiaridad y reserva {position:relative;}en ocasiones y sin causa o razón. Por lo general, la limpieza del caché ayudará, hasta que algo suceda y la peculiaridad vuelva a ocurrir.

Específicamente, desde la propia Apple Preparando su contenido web para iPad :

Safari en iPad y Safari en iPhone no tienen ventanas redimensionables. En Safari en iPhone y iPad, el tamaño de la ventana se establece en el tamaño de la pantalla (menos los controles de la interfaz de usuario de Safari) y el usuario no puede cambiarlo. Para moverse por una página web, el usuario cambia el nivel de zoom y la posición de la ventana gráfica al tocar dos veces o pellizcar para acercar o alejar, o al tocar y arrastrar para desplazar la página. A medida que un usuario cambia el nivel de zoom y la posición de la ventana gráfica, lo hace dentro de un área de contenido visible de tamaño fijo (es decir, la ventana). Esto significa que los elementos de la página web que tienen su posición "fija" en la ventana gráfica pueden terminar fuera del área de contenido visible, fuera de la pantalla.

Lo que es irónico, los dispositivos Android no parecen tener este problema. También es completamente posible usarlo {position:absolute;}en referencia a la etiqueta del cuerpo y no tener ningún problema.

Encontré la causa raíz de este capricho; que el evento de desplazamiento no se reproduce bien cuando se usa junto con la etiqueta HTML o BODY. A veces no le gusta iniciar el evento, o tendrá que esperar hasta que el evento de desplazamiento de desplazamiento finalice para recibir el evento. Específicamente, la ventana gráfica se vuelve a dibujar al final de este evento y los elementos fijos se pueden volver a colocar en otro lugar de la ventana gráfica.

Entonces, esto es lo que hago: (¡ evita usar la ventana gráfica y quédate con el 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>

En esencia, esto hará que el CUERPO sea del tamaño de la ventana gráfica y no desplazable. El DIV desplazable anidado en el interior se desplazará como lo haría normalmente el CUERPO (menos el efecto de oscilación, por lo que el desplazamiento se detiene en el toque). El DIV fijo permanece fijo sin interferencias.

Como nota al margen, un z-indexvalor alto en el DIV fijo es importante para mantener el DIV desplazable que parece estar detrás de él. Normalmente agrego eventos de cambio de tamaño y desplazamiento de ventana también para compatibilidad entre navegadores y resoluciones de pantalla alternativas.

Si todo lo demás falla, el código anterior también funcionará con los DIV fijos y desplazables establecidos en {position:absolute;}.

Talvi Watia
fuente
1

La forma simple de solucionar este problema simplemente escribe la propiedad de transformación para su elemento. y será arreglado Happy Coding :-)

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

También puedes probar a su manera, esto también funciona bien.

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

Esto podría no ser aplicable a todos los escenarios, pero descubrí que position: sticky(lo mismo con position: fixed) solo funciona en iPhones viejos cuando el contenedor de desplazamiento no es el cuerpo, sino dentro de otra cosa.

Ejemplo de pseudo html:

body                         <- scrollbar
   relative div
       sticky div

El div pegajoso se mantendrá en los navegadores de escritorio, pero con ciertos dispositivos, probados con: Chromium: herramientas de desarrollo: emulación del dispositivo: iPhone 6/7/8, y con Android 4 Firefox, no lo hará.

Lo que funcionará, sin embargo, es

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

En mi caso, fue porque el elemento fijo se mostraba usando una animación. Como se indica en este enlace :

en Safari 9.1, tener una posición: elemento fijo dentro de un elemento animado, puede hacer que la posición: elemento fijo no aparezca.

nnimis
fuente
-2

Aquí está mi solución a esto ...

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>

La explicación es que la posición fija para el div mantendrá el div en el fondo en todo momento, luego estiramos el div para ir a todas las esquinas del navegador (siempre que el margen del cuerpo = 0) usando (izquierda, derecha, arriba, abajo) ) simultaneamente.

Asegúrese de no utilizar el ancho y la altura, ya que esto anulará las opciones superior, izquierda, derecha e inferior.

Val
fuente