working with problem not chrome bar address 100vh html css css3 viewport-units

html - with - height 100vh not working in mobile



CSS3 100vh no constante en el navegador móvil (16)

Tengo un problema muy extraño ... en cada navegador y versión móvil encontré este comportamiento:

  • todos los navegadores tienen un menú superior cuando carga la página (que muestra la barra de direcciones, por ejemplo) que se desliza hacia arriba cuando comienza a desplazarse por la página.
  • 100vh a veces se calcula solo en la parte visible de una ventana gráfica, por lo que cuando la barra del navegador se desliza hacia arriba 100vh aumenta (en términos de píxeles)
  • Todos los diseños se vuelven a pintar y reajustar ya que las dimensiones han cambiado
  • un mal efecto nervioso para la experiencia del usuario

¿Cómo puede evitar este problema? Cuando escuché por primera vez sobre viewport-height, estaba emocionado y pensé que podría usarlo para bloques de altura fija en lugar de usar javascript, pero ahora creo que la única forma de hacerlo es, de hecho, javascript con algún evento de cambio de tamaño ...

puede ver el problema en: sitio de muestra

¿Alguien puede ayudarme / sugerir una solución CSS?

código de prueba simple:

/* maybe i can track the issue whe it occours... */ $(function(){ var resized = -1; $(window).resize(function(){ $(''#currenth'').val( $(''.vhbox'').eq(1).height() ); if (++resized) $(''#currenth'').css(''background:#00c''); }) .resize(); })

*{ margin:0; padding:0; } /* this is the box which should keep constant the height... min-height to allow content to be taller than viewport if too much text */ .vhbox{ min-height:100vh; position:relative; } .vhbox .t{ display:table; position:relative; width:100%; height:100vh; } .vhbox .c{ height:100%; display:table-cell; vertical-align:middle; text-align:center; }

<div class="vhbox" style="background-color:#c00"> <div class="t"><div class="c"> this div height should be 100% of viewport and keep this height when scrolling page <br> <!-- this input highlight if resize event is fired --> <input type="text" id="currenth"> </div></div> </div> <div class="vhbox" style="background-color:#0c0"> <div class="t"><div class="c"> this div height should be 100% of viewport and keep this height when scrolling page </div></div> </div> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>


@nils lo explicó claramente.

¿Qué sigue entonces?

Acabo de volver a usar % ''clásico'' relativo (porcentaje) en CSS.

A menudo es más esfuerzo implementar algo de lo que sería usar vh , pero al menos, tiene una solución bastante estable que funciona en diferentes dispositivos y navegadores sin fallas extrañas en la interfaz de usuario.


Acabo de encontrar una aplicación web que diseñé que tiene este problema con iPhones y iPads, y encontré un artículo que sugiere resolverlo usando consultas de medios dirigidas a dispositivos Apple específicos.

No sé si puedo compartir el código de ese artículo aquí, pero la dirección es esta: http://webdesignerwall.com/tutorials/css-fix-for-ios-vh-unit-bug

Citando el artículo: "simplemente haga coincidir la altura del elemento con la altura del dispositivo utilizando consultas de medios que se dirigen a las versiones anteriores de la resolución de iPhone y iPad"

Agregaron solo 6 consultas de medios para adaptar elementos de altura completa, y debería funcionar ya que está completamente implementado con CSS.

Editar pendiente: no puedo probarlo en este momento, pero volveré e informaré mis resultados.



Como no se solucionará, puede hacer algo como:

.my-element { height: 100vh; /* Fallback for browsers that do not support Custom Properties */ height: calc(var(--vh, 1vh) * 100); transition: 1s; /* To avoid a jumpy result */ }

Para mí fue la solución más rápida y más pura que jugar con JavaScript, que no podía funcionar en muchos dispositivos y navegadores.

Simplemente use el valor adecuado de vh que se ajuste a sus necesidades.


Como soy nuevo, no puedo comentar sobre otras respuestas.

Si alguien está buscando una respuesta para que esto funcione (y puede usar JavaScript, ya que parece ser necesario para que esto funcione en este momento), este enfoque me ha funcionado bastante bien y también explica el cambio de orientación móvil. Yo uso Jquery para el código de ejemplo, pero debería ser factible con vanillaJS.

-Primero, utilizo un script para detectar si el dispositivo es táctil o flotante. Ejemplo de huesos desnudos:

html { height: 100vh; } body { top: 0; left: 0; right: 0; bottom: 0; width: 100vw; } /* this is the container you want to take the visible viewport */ /* make sure this is top-level in body */ #your-app-container { height: 100%; }

Esto agrega clase al elemento del cuerpo de acuerdo con el tipo de dispositivo (desplazamiento o toque) que se puede usar más adelante para el script de altura.

-A continuación, use este código para establecer la altura del dispositivo en la carga y en el cambio de orientación:

# html <body> <div class="content"> <!-- Your stuff here --> </div> </body> # css .content { height: 80vh; }

-Timeout está configurado para que el dispositivo calcule la nueva altura correctamente en el cambio de orientación. Si no hay tiempo de espera, en mi experiencia, la altura no será correcta. 500 ms puede ser una exageración, pero ha funcionado para mí.

-100vh en dispositivos de desplazamiento es una alternativa si el navegador anula el CSS 100vh.


El siguiente código resolvió el problema (con jQuery).

if (jQuery(''body'').hasClass("touch-device")) { //Loading height on touch-device function calcFullHeight() { jQuery(''.hero-section'').css("height", $(window).height()); } (function($) { calcFullHeight(); jQuery(window).on(''orientationchange'', function() { // 500ms timeout for getting the correct height after orientation change setTimeout(function() { calcFullHeight(); }, 500); }); })(jQuery); } else { jQuery(''.hero-section'').css("height", "100vh"); }

Y los otros elementos usan % como una unidad para reemplazar vh .


El uso de vh en dispositivos móviles no funcionará con 100vh, debido a que sus opciones de diseño utilizan toda la altura del dispositivo sin incluir ninguna barra de direcciones, etc.

Si está buscando un diseño que incluya alturas div proporcionales a la altura de la vista real, uso la siguiente solución de CSS puro:

// First we get the viewport height and we multiple it by 1% to get a value for a vh unit let vh = window.innerHeight * 0.01; // Then we set the value in the --vh custom property to the root of the document document.documentElement.style.setProperty(''--vh'', `${vh}px`); // We listen to the resize event window.addEventListener(''resize'', () => { // We execute the same script as before let vh = window.innerHeight * 0.01; document.documentElement.style.setProperty(''--vh'', `${vh}px`); });

Tiene dos opciones para configurar la altura de la ventana gráfica, establezca manualmente --devHeight en una altura que funcione (pero deberá ingresar este valor para cada tipo de dispositivo para el que está codificando)

o

Use javascript para obtener la altura de la ventana y luego actualice --devheight al cargar y actualizar la ventana gráfica (sin embargo, esto requiere el uso de javascript y no es una solución pura de CSS)

Una vez que obtenga la altura de vista correcta, puede crear múltiples divisiones en un porcentaje exacto de la altura total de la ventana gráfica simplemente cambiando el multiplicador en cada división a la que asigna la altura.

0.10 = 10% de la altura de la vista 0.57 = 57% de la altura de la vista

Espero que esto pueda ayudar a alguien;)


Este es el truco que necesitará https://css-tricks.com/the-trick-to-viewport-units-on-mobile/ .

CSS

// First we get the viewport height and we multiple it by 1% to get a value for a vh unit let vh = window.innerHeight * 0.01; // Then we set the value in the --vh custom property to the root of the document document.documentElement.style.setProperty(''--vh'', `${vh}px`); // We listen to the resize event window.addEventListener(''resize'', () => { // We execute the same script as before let vh = window.innerHeight * 0.01; document.documentElement.style.setProperty(''--vh'', `${vh}px`); });

JS

body { background-color: #333; } .module { height: 100vh; /* Use vh as a fallback for browsers that do not support Custom Properties */ height: calc(var(--vh, 1vh) * 100); margin: 0 auto; max-width: 30%; } .module__item { align-items: center; display: flex; height: 20%; justify-content: center; } .module__item:nth-child(odd) { background-color: #fff; color: #F73859; } .module__item:nth-child(even) { background-color: #F73859; color: #F1D08A; }


Lo siguiente funcionó para mí:

:root { --devHeight: 86vh; //*This value changes } .div{ height: calc(var(--devHeight)*0.10); //change multiplier to suit required height }

El body tomará la altura de la ventana gráfica visible y #your-app-container with height: 100% hará que ese contenedor tome la altura de ventana gráfica visible.


Mira esta respuesta: https://css-tricks.com/the-trick-to-viewport-units-on-mobile/

<div class="module"> <div class="module__item">20%</div> <div class="module__item">40%</div> <div class="module__item">60%</div> <div class="module__item">80%</div> <div class="module__item">100%</div> </div>

var vhHeight = $("body").height(); var chromeNavbarHeight = vhHeight - window.innerHeight; $(''body'').css({ height: window.innerHeight, marginTop: chromeNavbarHeight });

if ("ontouchstart" in document.documentElement) { document.body.classList.add(''touch-device''); } else { document.body.classList.add(''hover-device''); }


Para muchos de los sitios que construyo, el cliente solicitará un banner de 100vh y, tal como lo ha encontrado, resulta en una mala experiencia "nerviosa" en el móvil cuando comienza a desplazarse. Así es como resuelvo el problema para una experiencia uniforme y uniforme en todos los dispositivos:

Primero configuré mi elemento de banner CSS en height:100vh

Luego uso jQuery para obtener la altura en píxeles de mi elemento de banner y aplicar un estilo en línea usando esta altura.

var viewportHeight = $(''.banner'').outerHeight(); $(''.banner'').css({ height: viewportHeight });

Hacer esto resuelve el problema en los dispositivos móviles, ya que cuando se carga la página, el elemento de banner se establece en 100vh usando CSS y luego jQuery anula esto al colocar CSS en línea en mi elemento de banner que evita que se redimensione cuando un usuario comienza a desplazarse.

Sin embargo, en el escritorio si un usuario cambia el tamaño de la ventana de su navegador, mi elemento de banner no cambiará de tamaño porque ahora tiene una altura fija establecida en píxeles debido a la jQuery anterior. Para abordar esto, uso Mobile Detect para agregar una clase ''móvil'' al cuerpo de mi documento. Y luego envuelvo el jQuery anterior en una declaración if:

if ($(''body'').hasClass(''mobile'')) { var viewportHeight = $(''.banner'').outerHeight(); $(''.banner'').css({ height: viewportHeight }); }

Como resultado, si un usuario está en un dispositivo móvil, la clase ''móvil'' está presente en el cuerpo de mi página y se ejecuta jQuery anterior. Por lo tanto, mi elemento de banner solo obtendrá el CSS en línea aplicado en dispositivos móviles, mientras que en el escritorio la regla CSS original de 100vh permanece en su lugar.


Puedes intentar dar position: fixed; top: 0; bottom: 0; position: fixed; top: 0; bottom: 0; propiedades a su contenedor.


Puedes probar min-height: -webkit-fill-available; en su CSS en lugar de 100vh . Debe ser resuelto


Se me ocurrió un componente React: échale un vistazo si usas React o exploras el código fuente si no lo haces, para que puedas adaptarlo a tu entorno.

Establece la altura del div de pantalla completa en window.innerHeight y luego lo actualiza en los cambios de tamaño de la ventana.


en mi aplicación lo hago así (mecanografiado y postcss anidado, así que cambie el código en consecuencia):

const appHeight = () => { const doc = document.documentElement doc.style.setProperty(''--app-height'', `${window.innerHeight}px`) } window.addEventListener(''resize'', appHeight) appHeight()

en tu css:

:root { --app-height: 100%; } html, body { padding: 0; margin: 0; overflow: hidden; width: 100vw; height: 100vh; @media not all and (hover:hover) { height: var(--app-height); } }

Funciona al menos en Chrome Mobile y iPad. Lo que no funciona es cuando agrega su aplicación a la pantalla de inicio en iOS y cambia la orientación varias veces; de alguna manera, los niveles de zoom se meten con el valor innerHeight, podría publicar una actualización si encuentro una solución.

Demo


Lamentablemente esto es intencional ...

Este es un problema bien conocido (al menos en safari mobile), que es intencional, ya que evita otros problemas. Benjamin Poulain respondió a un error del kit web :

Esto es completamente intencional. Tomó bastante trabajo de nuestra parte lograr este efecto. :)

El problema base es este: el área visible cambia dinámicamente a medida que se desplaza. Si actualizamos la altura de la vista CSS en consecuencia, debemos actualizar el diseño durante el desplazamiento. No solo eso parece una mierda, sino que hacerlo a 60 FPS es prácticamente imposible en la mayoría de las páginas (60 FPS es la velocidad de fotogramas de referencia en iOS).

Es difícil mostrarle la parte "parece una mierda", pero imagínese mientras se desplaza, el contenido se mueve y lo que desea en la pantalla cambia continuamente.

La actualización dinámica de la altura no funcionaba, teníamos algunas opciones: soltar las unidades de ventana gráfica en iOS, hacer coincidir el tamaño del documento como antes de iOS 8, usar el tamaño de vista pequeña, usar el tamaño de vista grande.

A partir de los datos que teníamos, usar el tamaño de vista más grande fue el mejor compromiso. La mayoría de los sitios web que utilizan unidades de ventana gráfica lucían geniales la mayor parte del tiempo.

Nicolas Hoizey ha investigado esto bastante: https://nicolas-hoizey.com/2015/02/viewport-height-is-taller-than-the-visible-part-of-the-document-in-some-mobile-browsers.html

No hay solución planificada

En este punto, no hay mucho que pueda hacer, excepto abstenerse de usar la altura de la ventana gráfica en dispositivos móviles. Chrome también cambió a esto en 2016: