L'image d'arrière-plan saute lorsque la barre d'adresse masque iOS / Android / Mobile Chrome

174

Je développe actuellement un site réactif en utilisant Twitter Bootstrap.

Le site a une image d'arrière-plan plein écran sur mobile / tablette / bureau. Ces images tournent et disparaissent chacune, en utilisant deux divs.

C'est presque parfait, sauf un problème. En utilisant iOS Safari, le navigateur Android ou Chrome sur Android, l'arrière-plan saute légèrement lorsqu'un utilisateur fait défiler la page et fait masquer la barre d'adresse.

Le site est ici: http://lt2.daveclarke.me/

Visitez-le sur un appareil mobile et faites défiler vers le bas et vous devriez voir l'image redimensionner / déplacer.

Le code que j'utilise pour le DIV d'arrière-plan est le suivant:

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

Toutes les suggestions sont les bienvenues - cela me fait la tête depuis un moment !!

Dave Clarke
la source
Votre lien nécessite une authentification ... aussi, montrez-nous quelques codes pls!
Shawn Taylor
Nouveau lien ajouté et code affiché pour le positionnement en arrière-plan, etc.
Dave Clarke
1
Si vous rencontrez ce problème, vous pouvez consulter les développeurs.google.com/ web/updates/2016/12/url-bar- resizing . Ce problème a (en quelque sorte) été résolu maintenant, mais affecte toujours les éléments qui l'ont fait position: fixed.
Adam Reis
@AdamReis enfin! Merci d'avoir posté
Dave Clarke

Réponses:

106

Ce problème est dû au rétrécissement / glissement des barres d'URL et à la modification de la taille des divs # bg1 et # bg2 puisqu'elles sont à 100% de hauteur et "fixes". Étant donné que l'image d'arrière-plan est réglée sur «couverture», elle ajustera la taille / position de l'image à mesure que la zone contenante est plus grande.

En fonction de la nature réactive du site, l'arrière-plan doit être mis à l'échelle. J'envisage deux solutions possibles:

1) Réglez la hauteur # bg1, # bg2 sur 100vh. En théorie, c'est une solution élégante. Cependant, iOS a un bogue vh ( http://thatemil.com/blog/2013/06/13/viewport-relative-unit-strangeness-in-ios-6/ ). J'ai essayé d'utiliser une hauteur maximale pour éviter le problème, mais il est resté.

2) La taille de la fenêtre, lorsqu'elle est déterminée par Javascript, n'est pas affectée par la barre d'URL. Par conséquent, Javascript peut être utilisé pour définir une hauteur statique sur # bg1 et # bg2 en fonction de la taille de la fenêtre. Ce n'est pas la meilleure solution car ce n'est pas du CSS pur et il y a un léger saut d'image lors du chargement de la page. Cependant, c'est la seule solution viable que je vois compte tenu des bogues "vh" d'iOS (qui ne semblent pas être corrigés dans iOS 7).

var bg = $("#bg1, #bg2");

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

$(window).resize(resizeBackground);
resizeBackground();

Sur une note latérale, j'ai vu tellement de problèmes avec ces barres d'URL de redimensionnement dans iOS et Android. Je comprends le but, mais ils doivent vraiment réfléchir aux fonctionnalités étranges et aux ravages qu'ils apportent aux sites Web. Le dernier changement est que vous ne pouvez plus "masquer" la barre d'URL lors du chargement de la page sur iOS ou Chrome à l'aide d'astuces de défilement.

EDIT: Bien que le script ci-dessus fonctionne parfaitement pour empêcher le redimensionnement de l'arrière-plan, il provoque un écart notable lorsque les utilisateurs font défiler vers le bas. C'est parce qu'il maintient la taille de l'arrière-plan à 100% de la hauteur de l'écran moins la barre d'URL. Si nous ajoutons 60px à la hauteur, comme le suggère swiss, ce problème disparaît. Cela signifie que nous ne pouvons pas voir les 60 pixels inférieurs de l'image d'arrière-plan lorsque la barre d'URL est présente, mais cela empêche les utilisateurs de voir un écart.

function resizeBackground() {
    bg.height( $(window).height() + 60);
}
Jason
la source
Merci pour cela. Je vais faire un tourbillon demain et vous faire savoir comment je vais :)
Dave Clarke
5
C'est merveilleux. J'ai implémenté votre deuxième solution, qui a fonctionné presque parfaitement avec seulement quelques pixels entre le pied de page et l'image d'arrière-plan. J'ai changé votre 4ème ligne de code en: bg.height(jQuery(window).height() + 60);qui fonctionne à merveille sur tous mes appareils! Merci :)
Dave Clarke
6
le bogue iOS vh est corrigé dans iOS8 mais le problème sur Android ne l'est pas. J'utilise des vhunités et bien sûr, 100vhc'est plus grand lorsque la barre d'adresse est masquée. C'est stupide que ce saut se produise après l'arrêt du défilement. Cela a juste l'air bogué. J'ai fini par utiliser la transition sur la hauteur pour la faire paraître intentionnelle.
ProblemsOfSumit
1
J'ai pu résoudre ce problème en déplaçant l'arrière-plan du bodyvers un wrapper <div>enveloppant tout le contenu de la page. Pas d'arrière-plans sautants sur iOS ou Android!
Marius Schulz
2
La solution JS ne fonctionne pas pour moi (Android). Confirmé que le script définit la hauteur, mais le problème persiste.
jwinn
61

J'ai trouvé que la réponse de Jason ne fonctionnait pas vraiment pour moi et que j'obtenais toujours un saut. Le Javascript assurait qu'il n'y avait pas d'espace en haut de la page mais l'arrière-plan sautait toujours chaque fois que la barre d'adresse disparaissait / réapparaissait. Donc, en plus du correctif Javascript, j'ai appliqué transition: height 999999sau div. Cela crée une transition d'une durée si longue qu'elle fige virtuellement l'élément.

AlexKempton
la source
24
Vous, monsieur, méritez +1 pour la vraie pensée hors de la boîte. Malheureusement, cela empêche d'ajuster la taille div à tout changement de taille d'écran, y compris par exemple ceux causés par la rotation de l'écran.
tobik
+1 pour la créativité! Vous devrez peut-être l'utiliser pour le moment car le problème se compose si vous utilisez vwou vhpour définir la taille de la police à l'intérieur de ce conteneur parent.
robabby
6
@tobik Il est toujours possible de réduire le saut causé par le changement de fenêtre en définissant une transition d'environ 0,5 seconde
binaryfunt
7
essayez de faire pivoter le téléphone maintenant
cuddlecheek
1
@tobik cela en fait en fait plus une fonctionnalité qu'un bug;) bonne réflexion
dimitrieh
23

J'ai un problème similaire sur un en-tête de notre site Web.

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

Cela se terminera par une expérience de défilement instable sur Android Chrome, car le .header-container sera redimensionné après que la barre d'url se soit masquée et que le doigt soit retiré de l'écran.

Solution CSS:

L'ajout des deux lignes suivantes empêchera que la barre d'url se cache et que le défilement vertical soit toujours possible:

html {
    overflow: hidden;
}
body {
    overflow-y: scroll;
    -webkit-overflow-scrolling:touch;
}
tapis
la source
4
Ouais, ça résout le problème comme tu le dis, mais ça craint que la barre de navigation soit toujours affichée. Sur certains téléphones, cela peut occuper une partie de l'espace d'écran précieux!
Dave Clarke
1
C'est vrai, pour éviter cela, vous pouvez également utiliser une solution de contournement JavaScript. Mais cet exemple fonctionne sans JS du tout.
tapis
3
Le défilement est complètement désactivé lorsque j'ai essayé cette solution.
Nithin Baby
1
Merci, cela a très bien fonctionné pour ma situation! Doit être mentionné pour toute autre personne qui pourrait le manquer que les balises html et body doivent être réglées à 100% de hauteur pour que cela fonctionne (au début, j'ai juste écrémé votre réponse au début et suis passé à la première mention de «solution»).
gburning
-webkit-overflow-scrolling ne doit pas être utilisé sur les sites de production. developer.mozilla.org/en-US/docs/Web/CSS/…
Fredrik Westerlund
16

Le problème peut être résolu avec une requête multimédia et quelques mathématiques. Voici une solution pour une orientation de portrait:

@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%);
}

Puisque vh changera lorsque la barre d'url disparaîtra, vous devez déterminer la hauteur d'une autre manière. Heureusement, la largeur de la fenêtre d'affichage est constante et les appareils mobiles ne sont proposés que dans quelques proportions différentes; si vous pouvez déterminer la largeur et le rapport hauteur / largeur, un peu de maths vous donnera la hauteur de la fenêtre exactement comme vh devrait fonctionner. Voici le processus

1) Créez une série de requêtes multimédias pour les proportions que vous souhaitez cibler.

  • utilisez le rapport d'aspect de l'appareil au lieu du rapport d'aspect car ce dernier se redimensionnera lorsque la barre d'URL disparaîtra

  • J'ai ajouté `` max '' au ratio d'aspect de l'appareil pour cibler tous les rapports d'aspect qui se trouvent entre les plus populaires. Ils ne seront pas aussi précis, mais ils ne le seront que pour une minorité d'utilisateurs et seront toujours assez proches du bon vh.

  • souvenez-vous de la requête multimédia en utilisant horizontal / vertical, donc pour le portrait, vous devrez inverser les chiffres

2) pour chaque requête multimédia, multipliez le pourcentage de hauteur verticale dans lequel vous voulez que l'élément vw soit par l'inverse du rapport hauteur / largeur.

  • Puisque vous connaissez la largeur et le rapport largeur / hauteur, il vous suffit de multiplier le% que vous voulez (100% dans votre cas) par le rapport hauteur / largeur.

3) Vous devez déterminer la hauteur de la barre d'URL, puis moins celle de la hauteur. Je n'ai pas trouvé de mesures exactes, mais j'utilise 9% pour les appareils mobiles en mode paysage et cela semble fonctionner assez bien.

Ce n'est pas une solution très élégante, mais les autres options ne sont pas non plus très bonnes, étant donné qu'elles sont:

  • Votre site Web semble bogué à l'utilisateur,

  • ayant des éléments de taille incorrecte, ou

  • Utilisation de javascript pour certains styles de base ,

L'inconvénient est que certains appareils peuvent avoir des hauteurs de barre d'URL ou des proportions différentes de celles des plus populaires. Cependant, en utilisant cette méthode si seul un petit nombre d'appareils subit l'ajout / la soustraction de quelques pixels, cela me semble beaucoup mieux que tout le monde ayant un site Web redimensionné lors du balayage.

Pour vous faciliter la tâche, j'ai également créé 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%);
  }
}
Jordan Los
la source
2
Très créatif! Pas un fan de la supposition de 9% cependant.
w00t
1
Très simple et intelligent! Vous pouvez ajouter un paramètre à vh-fix pour simuler le comportement d'origine: @mixin vh-fix($vh: 100)=>height: calc(100vw * (1.333 * $vh / 100) - 9%)
mjsarfatti
1
Ce qui précède devrait être:height: calc(100vw * (1.333 * #{$vh} / 100) - 9%)
mjsarfatti
Pour mon cas d'utilisation, cela a très bien fonctionné, et encore mieux une fois que j'ai supprimé le fichier -9%.
Ben Fleming
12

Toutes les réponses ici utilisent la windowhauteur, qui est affectée par la barre d'URL. Tout le monde a-t-il oublié la screentaille?

Voici ma solution 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);
  }
});

L'ajout de la .css()pièce modifie inévitablement l'élément positionné absolu aligné en haut en élément aligné en bas, il n'y a donc pas de saut du tout. Bien que, je suppose qu'il n'y a aucune raison de ne pas simplement ajouter cela directement au CSS normal.

Nous avons besoin du renifleur de l'agent utilisateur car la hauteur de l'écran sur les ordinateurs de bureau ne serait pas utile.

De plus, tout cela suppose #background qu'un élément à position fixe remplit la fenêtre.

Pour les puristes JavaScript (avertissement - non testé):

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: Désolé que cela ne répond pas directement à votre problème spécifique avec plus d'un arrière-plan. Mais c'est l'un des premiers résultats lors de la recherche de ce problème d'arrière-plans fixes sautant sur mobile.

cr0ybot
la source
2
J'ai essayé un million de ces réponses et c'est de loin la meilleure. Au départ, j'essayais de l'utiliser uniquement sur <body> car cela avait l'arrière-plan. L'utilisation d'un div pour envelopper la page entière a causé d'autres problèmes. Utiliser un div vide avec z-index: -1 comme arrière-plan semblait être la meilleure solution combinée avec ce qui précède. J'ai supprimé la détection mobile car faire cela sur le bureau ne nuit pas à mon site. Pas de maths (qui peuvent deviner la taille des onglets mal), aucun gestionnaire nécessaire pour le redimensionnement. L'arrière-plan n'est que l'écran entier, ancré en bas. Terminé. Aimer!
Evan Langlois
9

J'ai également rencontré ce problème lorsque j'essayais de créer un écran d'entrée qui couvrirait toute la fenêtre. Malheureusement, la réponse acceptée ne fonctionne plus.

1) Les éléments dont la hauteur est définie pour 100vhêtre redimensionnés chaque fois que la taille de la fenêtre change, y compris les cas où cela est causé par la (dés) apparition de la barre d'URL.

2) $(window).height()renvoie des valeurs également affectées par la taille de la barre d'URL.

Une solution est de "figer" l'élément en utilisant transition: height 999999scomme suggéré dans la réponse d'AlexKempton . L'inconvénient est que cela désactive effectivement l'adaptation à tous les changements de taille de la fenêtre, y compris ceux provoqués par la rotation de l'écran.

Ma solution consiste donc à gérer manuellement les modifications de la fenêtre à l'aide de JavaScript. Cela me permet d'ignorer les petits changements qui sont susceptibles d'être causés par la barre d'URL et de ne réagir que sur les plus grands.

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: J'utilise en fait cette technique avec height: 100vh. La page est rendue correctement dès le début, puis le javascript entre et commence à gérer la hauteur manuellement. De cette façon, il n'y a aucun scintillement pendant le chargement de la page (ou même après).

tobik
la source
1
J'ai utilisé quelque chose de similaire, mais plutôt que de définir height: 100vhdans le CSS initial, j'ai défini min-height:100vhpuis, lors du redimensionnement de la fenêtre, je calcule le min-heightet le règle à la hauteur du port de vue. Ceci est pratique lorsque votre site est affiché sur de petits écrans et que le contenu est trop volumineux pour tenir dans la fenêtre. Un ensemble anti-rebond / accélérateur sur l'événement de redimensionnement permet d'améliorer les performances de certains navigateurs (le redimensionnement a tendance à se déclencher très souvent)
Troy Morehouse
Je pense qu'à un certain moment, j'ai également essayé d'utiliser à la min-heightplace, mais j'ai rencontré un problème lorsque j'avais besoin de centrer verticalement le contenu interne. Le centrage vertical peut devenir délicat lorsque l'élément extérieur est heightréglé sur auto. J'ai donc proposé une hauteur minimale fixe qui devrait être suffisante pour contenir tout type de contenu possible et la définir dans le CSS initial. Depuis min-heighta une priorité plus élevée que height, cela fonctionne plutôt bien.
tobik
Ah ouais, j'ai eu le même problème, mais je l'ai résolu en changeant le jumbotron en display: table, puis en réglant le conteneur interne sur display: table-cellavec vertical-align: middle. A travaillé comme un charme.
Troy Morehouse
Vraiment? Parce que j'ai essayé la même approche mais j'ai échoué. Je ne me souviens pas vraiment quel était le problème, mais cela pourrait être pertinent: stackoverflow.com/questions/7790222/…
tobik
Assurez-vous simplement d'éviter le remplissage en pourcentage ou les marges. A causé quelques problèmes de rendu étranges sur IE8, bien que les navigateurs modernes soient corrects.
Troy Morehouse
8

La solution que je utilise actuellement est de vérifier la userAgentsur $(document).readypour voir si elle est l' un des navigateurs fautifs. Si tel est le cas, procédez comme suit:

  1. Définissez les hauteurs pertinentes sur la hauteur actuelle de la fenêtre plutôt que sur «100%»
  2. Stocker la valeur horizontale de la fenêtre courante
  3. Ensuite, activé $(window).resize, ne mettez à jour les valeurs de hauteur pertinentes que si la nouvelle dimension horizontale de la fenêtre est différente de sa valeur initiale
  4. Stocker les nouvelles valeurs horizontales et verticales

Si vous le souhaitez, vous pouvez également tester l'autorisation des redimensionnements verticaux uniquement lorsqu'ils sont au-delà de la hauteur des barres d'adresse.

Oh, et la barre d'adresse affecte $(window).height. Voir: Modification de la barre d'adresse du navigateur Webkit mobile (chrome) $ (window) .height (); faire background-size: la couverture est remise à l'échelle à chaque fois JS "Window" largeur-hauteur vs "écran" largeur-hauteur?

mp
la source
Je n'ai pas essayé cela, mais votre premier point ne fonctionnerait-il pas pour iOS? ( thatemil.com/blog/2013/06/13/… )
Dave Clarke
J'ai corrigé sa valeur dans la première étape, mais je suis surpris que vous ayez trouvé la réponse de Jason pour résoudre le problème. Comme indiqué, j'ai trouvé, avec l'autre utilisateur dans la question précédente que j'ai liée, que la valeur de la méthode $ (window) .height () change lorsque la barre d'adresse dans Chrome sur Android est ou n'est pas visible. J'ai jeté ensemble ce petit site qui révèle juste le résultat $ (window) .height () dans une alerte, et il fournit définitivement des valeurs différentes sur mon nexus 4 en chrome lorsque la barre d'adresse est / n'est pas visible: stormy-meadow-5908 .herokuapp.com
mp
Cela résout à 100% le problème sur mon appareil Android bien que je vois un problème similaire sur mon iPad qui ne semble pas résoudre ce que je suis toujours en train de rechercher.
Dave Clarke
Êtes-vous en mesure de fournir du code pour votre solution et je vais l'essayer?
Dave Clarke
4

J'ai trouvé une solution vraiment simple sans utiliser Javascript:

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

Tout cela retarde le mouvement pour qu'il soit incroyablement lent qu'il ne soit pas perceptible.

Pav Sidhu
la source
@ Tyguy7 Cela fonctionne bien chaque fois que votre hauteur n'est pas définie sur une valeur fixe, c'est 100%-à- dire 100vh. IE8 est le seul navigateur majeur qui ne prend pas en charge les transitions.
Pav Sidhu
Solution géniale et simple!
zdarsky.peter
3
Cela fonctionne très bien jusqu'à ce que vous soyez sur un appareil sur lequel vous pouvez passer du portrait au paysage. Lorsque cela se produit, le design est ruiné.
Nagy Nick
@NagyNick ce n'était pas un si gros problème pour moi. Vous pouvez détecter le changement d'orientation dans Javascript et ajuster l'image d'arrière-plan.
Pav Sidhu
3

Ma solution impliquait un peu de javascript. Gardez le 100% ou 100vh sur le div (cela évitera que le div n'apparaisse au chargement initial de la page). Ensuite, lorsque la page se charge, saisissez la hauteur de la fenêtre et appliquez-la à l'élément en question. Évite le saut car maintenant vous avez une hauteur statique sur votre div.

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

$hero.css('height', h);
Todd Miller
la source
3

J'ai créé une solution javascript vanille pour utiliser les unités VH. L'utilisation de VH à peu près n'importe où est effectuée par des barres d'adresse minimisées lors du défilement. Pour corriger le jank qui apparaît lorsque la page se redessine, j'ai ce js ici qui va saisir tous vos éléments en utilisant des unités VH (si vous leur donnez la classe .vh-fix) et leur donner des hauteurs de pixels en ligne. Essentiellement les congeler à la hauteur que nous voulons. Vous pouvez le faire lors de la rotation ou lors du changement de taille de la fenêtre pour rester réactif.

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

Cela a résolu tous mes cas d'utilisation, j'espère que cela aide.

Geek Devigner
la source
3

c'est ma solution pour résoudre ce problème, j'ai ajouté des commentaires directement sur le code. J'ai testé cette solution et fonctionne très bien. J'espère que nous serons utiles pour tout le monde a le même problème.

//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
  }); 
};
lino
la source
1
Vous appelez setHeight () dans la méthode changeHeight si la requête correspond et également si elle ne correspond pas. Supprimez donc simplement l'instruction if car elle n'est pas nécessaire.
Dennis Meissner
2

C'est la meilleure solution (la plus simple) au-dessus de tout ce que j'ai essayé.

... Et cela ne garde pas l'expérience native de la barre d'adresse !

Vous pouvez définir la hauteur avec CSS à 100% par exemple, puis définir la hauteur à 0,9 * de la hauteur de la fenêtre en px avec javascript, lorsque le document est chargé.

Par exemple avec jQuery:

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

)

Malheureusement, il n'y a rien qui fonctionne avec du CSS pur: P, mais soyez aussi minuscule vhet vwbogue sur les iPhones - utilisez des pourcentages.


la source
1

J'ai défini mon élément width, avec javascript. Après avoir réglé le 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");

Cela fonctionne pour moi. Je n'utilise pas jquery ect. parce que je veux qu'il se charge dès que possible.

Johan Hoeksma
la source
1

Il a fallu quelques heures pour comprendre tous les détails de ce problème et trouver la meilleure implémentation. Il s'avère qu'en avril 2016, seul iOS Chrome a ce problème. J'ai essayé sur Android Chrome et iOS Safari - les deux allaient bien sans ce correctif. Donc, le correctif pour iOS Chrome que j'utilise est:

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

Réponse simple si votre arrière-plan le permet, pourquoi ne pas définir background-size: à quelque chose couvrant juste la largeur de l'appareil avec des requêtes multimédias et à utiliser à côté de: après position: fixe; pirater ici .

IE: taille de fond: 901px; pour tous les écrans <900px? Pas parfait ou réactif, mais cela a fonctionné un charme pour moi sur mobile <480px car j'utilise un BG abstrait.

PâquesMédia
la source
0

J'utilise cette solution de contournement: corrigez la hauteur de bg1 lors du chargement de la page en:

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

Ensuite, attachez un écouteur d'événement de redimensionnement à Window qui fait ceci: si la différence de hauteur après le redimensionnement est inférieure à 60px (rien de plus que la hauteur de la barre d'URL), ne faites rien et si elle est supérieure à 60px, redéfinissez la hauteur de bg1 à la hauteur de son parent! code complet:

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: Ce bug est tellement irritant!

AadityaTaparia
la source
0

Similaire à la réponse @AlexKempton. (impossible de commenter désolé)

J'ai utilisé de longs délais de transition pour empêcher le redimensionnement de l'élément.

par exemple:

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

Le compromis avec ceci est qu'il empêche le redimensionnement de l'élément, y compris sur la rotation de l'appareil, cependant, vous pouvez utiliser un peu de JS pour détecter orientationchangeet réinitialiser la hauteur s'il s'agissait d'un problème.

Chris Anderson
la source
0

Pour ceux qui souhaitent écouter la hauteur intérieure réelle et le défilement vertical de la fenêtre pendant que le navigateur mobile Chrome fait la transition de la barre d'URL de montré à masqué et vice versa, la seule solution que j'ai trouvée est de définir une fonction d'intervalle, et mesurer l'écart de la window.innerHeightavec sa valeur précédente.

Ceci introduit ce code:

var innerHeight = window.innerHeight;
window.setInterval(function ()
{
  var newInnerHeight = window.innerHeight;
  if (newInnerHeight !== innerHeight)
  {
    var newScrollY = window.scrollY + newInnerHeight - innerHeight;
    // ... do whatever you want with this new scrollY
    innerHeight = newInnerHeight;
  }
}, 1000 / 60);

J'espère que ce sera pratique. Quelqu'un connaît-il une meilleure solution?

Édouard Mercier
la source
0

La solution que j'ai trouvée en cas de problème similaire était de définir la hauteur de l'élément à window.innerHeightchaque fois touchmovequ'un événement était déclenché.

var lastHeight = '';

$(window).on('resize', function () {
    // remove height when normal resize event is fired and content redrawn
    if (lastHeight) {
        $('#bg1').height(lastHeight = '');
    }
}).on('touchmove', function () {
    // when window height changes adjust height of the div
    if (lastHeight != window.innerHeight) {
        $('#bg1').height(lastHeight = window.innerHeight);
    }
});

Cela permet à l'élément de couvrir exactement 100% de l'écran disponible à tout moment, ni plus ni moins. Même pendant le masquage ou l'affichage de la barre d'adresse.

Néanmoins, il est dommage que nous devions trouver ce genre de correctifs, où le simple position: fixeddevrait fonctionner.

Paul
la source
0

Avec la prise en charge des propriétés personnalisées CSS (variables) dans iOS, vous pouvez les définir avec JS et les utiliser uniquement sur iOS.

const iOS = /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream;
if (iOS) {
  document.body.classList.add('ios');
  const vh = window.innerHeight / 100;
  document.documentElement.style
    .setProperty('--ios-10-vh', `${10 * vh}px`);
  document.documentElement.style
    .setProperty('--ios-50-vh', `${50 * vh}px`);
  document.documentElement.style
    .setProperty('--ios-100-vh', `${100 * vh}px`);
}
body.ios {
    .side-nav {
        top: var(--ios-50-vh);
    }
    section {
        min-height: var(--ios-100-vh);
        .container {
            position: relative;
            padding-top: var(--ios-10-vh);
            padding-bottom: var(--ios-10-vh);
        }
    }
}
Stephen Saucier
la source
0

Ma réponse est pour tous ceux qui viennent ici (comme moi) pour trouver une réponse à un bug causé par le masquage de l'adresse nue / de l'interface du navigateur.

La barre d'adresse masquée provoque le déclenchement de l'événement de redimensionnement. Mais différent des autres événements de redimensionnement, comme le passage en mode paysage, cela ne change pas la largeur de la fenêtre. Ma solution est donc de m'accrocher à l'événement de redimensionnement et de vérifier si la largeur est la même.

// Keep track of window width
let myWindowWidth = window.innerWidth;

window.addEventListener( 'resize', function(event) {

    // If width is the same, assume hiding address bar
    if( myWindowWidth == window.innerWidth ) {
         return;
    }

    // Update the window width
    myWindowWidth = window.innerWidth;

    // Do your thing
    // ...
});
Erik J.
la source