La imagen de fondo salta cuando la barra de direcciones oculta iOS / Android / Mobile Chrome

Actualmente estoy desarrollando un sitio de respuesta usando Twitter Bootstrap.

El sitio tiene una imagen de fondo de pantalla completa a través de móvil / tablet / escritorio. Estas imágenes giran y se desvanecen a través de cada uno, utilizando dos divs.

Es casi perfecto, excepto un problema. Con iOS Safari, Android Browser o Chrome en Android, el fondo salta ligeramente cuando un usuario desplaza hacia abajo la página y hace que la barra de direcciones se oculte.

El sitio está aquí: http://lt2.daveclarke.me/

Visítelo en un dispositivo móvil y desplácese hacia abajo y debería ver el cambio de tamaño / movimiento de la imagen.

El código que estoy utilizando para el fondo DIV es el siguiente:

#bg1 { background-color: #3d3d3f; background-repeat:no-repeat; background-attachment:fixed; background-position:center center; -webkit-background-size: cover; -moz-background-size: cover; -o-background-size: cover; background-size: cover; position:fixed; width:100%; height:100%; left:0px; top:0px; z-index:-1; display:none; } 

Todas las sugerencias bienvenido – esto ha estado haciendo mi cabeza en un tiempo!

Este problema se debe a que las barras de URL se reducen / se deslizan fuera del camino y cambian el tamaño de las divisiones # bg1 y # bg2 ya que son 100% de altura y "fixed". Puesto que la imagen de fondo está ajustada a "cubrir", ajustará el tamaño / posición de la imagen cuando el área que contiene sea mayor.

Basado en la naturaleza responsiva del sitio, el fondo debe escalar. Tengo dos soluciones posibles:

1) Ajuste la altura # bg1, # bg2 a 100vh. En teoría, esta es una solución elegante. Sin embargo, iOS tiene un error vh ( http://thatemil.com/blog/2013/06/13/viewport-relative-unit-strangeness-in-ios-6/ ). Intenté usar una altura máxima para evitar el problema, pero se mantuvo.

2) El tamaño de la ventana gráfica, cuando está determinado por Javascript, no se ve afectado por la barra de URL. Por lo tanto, se puede usar Javascript para establecer una altura estática en # bg1 y # bg2 en función del tamaño de la ventana gráfica. Esta no es la mejor solución, ya que no es pura CSS y hay un leve salto de imagen en la carga de la página. Sin embargo, es la única solución viable que veo teniendo en cuenta los bugs "vh" de iOS (que no parecen estar solucionados en iOS 7).

 var bg = $("#bg1, #bg2"); function resizeBackground() { bg.height($(window).height()); } $(window).resize(resizeBackground); resizeBackground(); 

En una nota lateral, he visto tantos problemas con estas barras de redimensionamiento de URL en iOS y Android. Entiendo el propósito, pero realmente necesitan pensar en la extraña funcionalidad y estragos que traen a los sitios web. El último cambio, es que ya no se puede ocultar la barra de URL en la carga de la página en iOS o Chrome mediante trucos de desplazamiento.

EDIT: Mientras que el script anterior funciona perfectamente para mantener el fondo de cambio de tamaño, provoca una brecha notable cuando los usuarios desplazarse hacia abajo. Esto es porque está manteniendo el fondo de tamaño al 100% de la altura de la pantalla menos la barra de URL. Si añadimos 60px a la altura, como suiza sugiere, este problema desaparece. Significa que no llegamos a ver el 60px inferior de la imagen de fondo cuando la barra de URL está presente, pero impide que los usuarios vean una brecha.

 function resizeBackground() { bg.height( $(window).height() + 60); } 

Me pareció que la respuesta de Jason no estaba funcionando para mí y todavía estaba recibiendo un salto. El Javascript aseguraba que no había ninguna brecha en la parte superior de la página, pero el fondo seguía saltando cuando la barra de direcciones desapareció / reapareció. Así, así como la corrección de Javascript, he aplicado la transition: height 999999s a la div. Esto crea una transición con una duración tan larga que prácticamente congela el elemento.

Tengo un problema similar en una cabecera de nuestro sitio web.

 html, body { height:100%; } .header { height:100%; } 

Esto terminará en una experiencia de desplazamiento con saltos en cromo android, porque el contenedor .header cambiará de escala después de que la url-barra se esconda y el dedo se quite de la pantalla.

Solución CSS:

Añadiendo las dos líneas siguientes, evitará que la url-barra se oculte y el desplazamiento vertical sea posible:

 html { overflow: hidden; } body { overflow-y: scroll; -webkit-overflow-scrolling:touch; } 

El problema se puede resolver con una consulta de medios y algunas matemáticas. He aquí una solución para una orientación portait:

 @media (max-device-aspect-ratio: 3/4) { height: calc(100vw * 1.333 - 9%); } @media (max-device-aspect-ratio: 2/3) { height: calc(100vw * 1.5 - 9%); } @media (max-device-aspect-ratio: 10/16) { height: calc(100vw * 1.6 - 9%); } @media (max-device-aspect-ratio: 9/16) { height: calc(100vw * 1.778 - 9%); } 

Puesto que vh cambiará cuando la barra del ur desaparece, usted necesita determinar la altura otra manera. Afortunadamente, el ancho de la ventana de visualización es constante y los dispositivos móviles sólo vienen en unas proporciones de aspecto diferentes; Si se puede determinar el ancho y la relación de aspecto, un poco de matemáticas le dará la altura de la ventana exactamente como vh debería funcionar. Aquí está el proceso

1) Cree una serie de consultas de medios para las relaciones de aspecto que desea segmentar.

  • Use device-aspect-ratio en lugar de aspect-ratio porque este último cambiará el tamaño cuando la barra de ur desaparece

  • He añadido "max" a la relación de aspecto del dispositivo para orientar cualquier relación de aspecto que suceda entre los más populares. No serán tan precisos, pero serán sólo para una minoría de usuarios y seguirán siendo bastante cercanos al vh adecuado.

  • Recuerde la consulta de medios utilizando horizontal / vertical, por lo que para portait tendrá que voltear los números

2) para cada consulta de medios multiplique cualquier porcentaje de altura vertical que desee que el elemento esté en vw por el reverso de la relación de aspecto.

  • Puesto que usted sabe el ancho y la proporción de ancho a la altura, usted apenas multiplica el% que usted quiere (100% en su caso) por la relación de la altura / de la anchura.

3) Usted tiene que determinar la altura de la barra de url, y luego menos que de la altura. No he encontrado medidas exactas, pero uso el 9% para dispositivos móviles en el paisaje y que parece funcionar bastante bien.

Esta no es una solución muy elegante, pero las otras opciones tampoco son muy buenas, considerando que son:

  • Tener su sitio web parece buggy para el usuario,

  • Tener elementos de tamaño inadecuado, o

  • Usando javascript para un estilo básico ,

El inconveniente es que algunos dispositivos pueden tener diferentes alturas de barra de url o relaciones de aspecto que los más populares. Sin embargo, utilizando este método si sólo un pequeño número de dispositivos sufren la adición / sustracción de unos pocos píxeles, que parece mucho mejor para mí que todos los que tienen un sitio web cambiar el tamaño al pasar.

Para hacerlo más fácil, también creé un mixin SASS:

 @mixin vh-fix { @media (max-device-aspect-ratio: 3/4) { height: calc(100vw * 1.333 - 9%); } @media (max-device-aspect-ratio: 2/3) { height: calc(100vw * 1.5 - 9%); } @media (max-device-aspect-ratio: 10/16) { height: calc(100vw * 1.6 - 9%); } @media (max-device-aspect-ratio: 9/16) { height: calc(100vw * 1.778 - 9%); } } 

Todas las respuestas aquí están usando la altura de la window , que es afectada por la barra de URL. ¿Todos se han olvidado de screen altura de la screen ?

Aquí está mi solución jQuery:

 $(function(){ var $w = $(window), $background = $('#background'); // Fix background image jump on mobile if ((/Android|iPhone|iPad|iPod|BlackBerry/i).test(navigator.userAgent || navigator.vendor || window.opera)) { $background.css({'top': 'auto', 'bottom': 0}); $w.resize(sizeBackground); sizeBackground(); } function sizeBackground() { $background.height(screen.height); } }); 

Agregar la parte .css() está cambiando inevitablemente el elemento posicionado absoluto superior alineado a alineado inferior, por lo que no hay salto en absoluto. Aunque, supongo que no hay razón para no agregar eso directamente al CSS normal.

Necesitamos el sniffer del agente del usuario porque la altura de la pantalla en los escritorios no sería provechosa.

Además, esto es todo suponiendo que #background es un elemento de posición fija que llena la ventana.

Para los puristas de JavaScript (warning – untested):

 var background = document.getElementById('background'); // Fix background image jump on mobile if ((/Android|iPhone|iPad|iPod|BlackBerry/i).test(navigator.userAgent || navigator.vendor || window.opera)) { background.style.top = 'auto'; background.style.bottom = 0; window.onresize = sizeBackground; sizeBackground(); } function sizeBackground() { background.style.height = screen.height; } 

EDIT: Lo sentimos que esto no responde directamente a su problema específico con más de un fondo. Pero este es uno de los primeros resultados al buscar este problema de fondos fijos saltando en el móvil.

La solución que estoy utilizando actualmente es comprobar el userAgent en $(document).ready para ver si es uno de los navegadores que ofenden. Si es así, siga estos pasos:

  1. Establezca las alturas correspondientes a la altura actual de la ventana gráfica en lugar de "100%"
  2. Almacenar el valor horizontal de la ventana de visualización actual
  3. Luego, en $(window).resize , solo actualiza los valores de altura relevantes si la nueva dimensión de la ventana horizontal es diferente de su valor inicial
  4. Almacenar los nuevos valores horizontales y verticales

Opcionalmente, también se puede probar permitiendo redimensionar verticalmente sólo cuando estén más allá de la altura de las barras de direcciones.

Ah, y la barra de direcciones sí afecta a $(window).height . Consulte: La barra de direcciones de Mobile Webkit (cromo) cambia $ (ventana) .height (); Haciendo fondo-tamaño: la cubierta rescale cada vez JS "Ventana" anchura-altura contra "pantalla" anchura-altura?

Me encontré con este problema también cuando estaba tratando de crear una pantalla de entrada que cubriría la vista completa. Desafortunadamente, la respuesta aceptada ya no funciona.

1) Los elementos con la altura establecida en 100hv se 100hv tamaño cada vez que cambia el tamaño de la ventana de visualización, incluidos los casos en que es causada por (dis) la barra de URL que aparece.

2) $(window).height() devuelve valores también afectados por el tamaño de la barra de URL.

Una solución es "congelar" el elemento mediante la transition: height 999999s como se sugiere en la respuesta de AlexKempton . La desventaja es que esto efectivamente deshabilita la adaptación a todos los cambios de tamaño de la ventana de visualización, incluidos los causados ​​por la rotación de la pantalla.

Así que mi solución es gestionar manualmente los cambios de la ventana gráfica con JavaScript. Eso me permite ignorar los pequeños cambios que es probable que sean causados ​​por la barra de URL y reaccionar sólo en los grandes.

 function greedyJumbotron() { var HEIGHT_CHANGE_TOLERANCE = 100; // Approximately URL bar height in Chrome on tablet var jumbotron = $(this); var viewportHeight = $(window).height(); $(window).resize(function () { if (Math.abs(viewportHeight - $(window).height()) > HEIGHT_CHANGE_TOLERANCE) { viewportHeight = $(window).height(); update(); } }); function update() { jumbotron.css('height', viewportHeight + 'px'); } update(); } $('.greedy-jumbotron').each(greedyJumbotron); 

EDIT: Yo realmente uso esta técnica junto con la height: 100hv . La página se representa correctamente desde el principio y luego el JavaScript inicia y comienza a administrar la altura manualmente. De esta manera no hay parpadeo en absoluto mientras la página se está cargando (o incluso después).

He encontrado una solución realmente fácil sin el uso de Javascript:

 transition: height 1000000s ease; -webkit-transition: height 1000000s ease; -moz-transition: height 1000000s ease; -o-transition: height 1000000s ease; 

Todo esto hace es retrasar el movimiento de modo que es increíblemente lento que no es notable.

Mi solución implicaba un poco de javascript. Mantenga el 100% o 100vh en la div (esto evitará que la div no aparezca en la carga inicial de la página). Luego, cuando la página se cargue, tome la altura de la ventana y aplíquela al elemento en cuestión. Evita el salto porque ahora tienes una altura estática en tu div.

 var $hero = $('#hero-wrapper'), h = window.innerHeight; $hero.css('height', h); 

He creado una solución de javascript de vainilla para el uso de unidades VH. El uso de VH prácticamente en cualquier lugar se realiza mediante barras de direcciones que minimizan el desplazamiento. Para arreglar el jank que muestra cuando la página se vuelve a dibujar, tengo este js aquí que agarra todos tus elementos usando unidades VH (si les das la clase .vh-fix ), y les doy las alturas de píxeles. Esencialmente congelándolos a la altura que queremos. Usted podría hacer esto en la rotación o en cambio del tamaño del viewport para permanecer responsivo.

 var els = document.querySelectorAll('.vh-fix') if (!els.length) return for (var i = 0; i < els.length; i++) { var el = els[i] if (el.nodeName === 'IMG') { el.onload = function() { this.style.height = this.clientHeight + 'px' } } else { el.style.height = el.clientHeight + 'px' } } 

Esto ha resuelto todos mis casos de uso, espero que ayude.

Esta es mi solución para resolver este problema, he añadido comentarios directamente en el código. He probado esta solución y funciona bien. Espero que sea útil para todos tiene el mismo problema.

 //remove height property from file css because we will set it to first run of page //insert this snippet in a script after declarations of your scripts in your index var setHeight = function() { var h = $(window).height(); $('#bg1, #bg2').css('height', h); }; setHeight(); // at first run of webpage we set css height with a fixed value if(typeof window.orientation !== 'undefined') { // this is more smart to detect mobile devices because desktop doesn't support this property var query = window.matchMedia("(orientation:landscape)"); //this is is important to verify if we put var changeHeight = function(query) { //mobile device in landscape mode if (query.matches) { // if yes we set again height to occupy 100% setHeight(); // landscape mode } else { //if we go back to portrait we set again setHeight(); // portrait mode } } query.addListener(changeHeight); //add a listner too this event } else { //desktop mode //this last part is only for non mobile $( window ).resize(function() { // so in this case we use resize to have setHeight(); // responsivity resisizing browser window }); }; 

Esta es la mejor solución (más simple) por encima de todo lo que he intentado.

… Y esto no mantiene la experiencia nativa de la barra de direcciones !

Puede configurar la altura con CSS al 100% por ejemplo y, a continuación, establecer la altura a 0,9 * de la altura de la ventana en px con javascript, cuando se carga el documento.

Por ejemplo con jQuery:

$("#element").css("height", 0.9*$(window).height());

)

Por desgracia, no hay nada que funcione con pura CSS: P, sino también ser minfull que vh y vw son buggy en iPhones – porcentajes de uso.

He establecido mi elemento de ancho, con javascript. Después de establecer el de vh.

Html

 <div id="gifimage"><img src="back_phone_back.png" style="width: 100%"></div> 

Css

 #gifimage { position: absolute; height: 70vh; } 

Javascript

 imageHeight = document.getElementById('gifimage').clientHeight; // if (isMobile) document.getElementById('gifimage').setAttribute("style","height:" + imageHeight + "px"); 

Esto funciona para mí. No utilizo jquery ect. Porque quiero que se cargue lo antes posible.

Tomó algunas horas para entender todos los detalles de este problema y averiguar la mejor aplicación. Resulta que a partir de abril de 2016 sólo iOS Chrome tiene este problema. He probado en Android Chrome y iOS Safari – ambos estaban bien sin esta corrección. Así que la solución para iOS Chrome que estoy usando es:

 $(document).ready(function() { var screenHeight = $(window).height(); $('div-with-background-image').css('height', screenHeight + 'px'); }); 

Estoy utilizando esta solución: Corregir altura de bg1 en carga de página por:

 var BG = document.getElementById('bg1'); BG.style.height = BG.parentElement.clientHeight; 

A continuación, adjuntar un oyente de evento de redimensionamiento a la ventana que hace esto: si la diferencia de altura después de cambiar el tamaño es inferior a 60px (nada más que la altura de la barra url), entonces no hacer nada y si es mayor que 60px a continuación, establecer la altura bg1 de nuevo a la altura de su padre! Código completo:

 window.addEventListener("resize", onResize, false); var BG = document.getElementById('bg1'); BG.style.height = BG.parentElement.clientHeight; var oldH = BG.parentElement.clientHeight; function onResize() { if(Math.abs(oldH - BG.parentElement.clientHeight) > 60){ BG.style.height = BG.parentElement.clientHeight + 'px'; oldH = BG.parentElement.clientHeight; } } 

PS: Este error es tan irritante!

Similar a @AlexKempton respuesta. (No puedo comentar lo siento)

He estado utilizando largos retrasos de transición para evitar que el elemento cambie el tamaño.

p.ej:

 transition: height 250ms 600s; /*10min delay*/ 

La compensación con esto es que evita el cambio de tamaño del elemento, incluso en el dispositivo de rotación, sin embargo, podría utilizar algunos JS para detectar orientationchange y restablecer la altura si se trataba de un problema.

  • Android azure servicios móviles __includeDeleted en pull?
  • Sugerencia de marco de interfaz de usuario para Ember.js HTM5 => Aplicación Phone Gap (o pila alternativa)
  • PhoneGap jQuery-Mobile aplicación que utiliza tanto local y páginas de servidor
  • ¿Para dividir un círculo en diferentes regiones para un tablero de dardos?
  • Sobre la actualización de aire con React Native
  • Ocultar barra de direcciones no funciona - se necesita el método a prueba de balas
  • Impactos de rendimiento de Cordova / PhoneGap?
  • Cómo guardar / cargar datos en línea (almacenar datos con AJAX y JSON) y sin conexión (localmente)
  • ¿Reacciona imágenes remotas de caché nativo?
  • Compras en la aplicación: compartir las compras en la aplicación entre Android e iOS
  • Cómo grabar audio en la página web (iOS, Android, PC / Mac) - sin flash
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.