CSS Media Query – Pauses-clavier pour les règles d’orientation – solution alternative?

Je travaille avec plusieurs tablettes – à la fois Android et iOS . Actuellement, j’ai les variations de résolution suivantes pour toutes les tablettes.

  • 1280 x 800
  • 1280 x 768
  • 1024 x 768 (iPad évidemment) – iPad n’a pas ce problème

Le moyen le plus simple d’appliquer le style basé sur l’orientation du périphérique consiste à utiliser l’orientation de la requête multimédia à l’aide de la syntaxe suivante.

@media all and (orientation:portrait) { /* My portrait based CSS here */ } @media all and (orientation:landscape) { /* My landscape based CSS here */ } 

Cela fonctionne parfaitement sur toutes les tablettes. MAIS , le problème est que lorsque l’appareil est en mode portrait et que l’utilisateur appuie sur n’importe quel champ de saisie (par exemple, recherche), le clavier logiciel apparaît, ce qui réduit la zone visible de la page Web. Sur les tablettes Android, cela dépend de la hauteur du clavier. Donc, finalement, la page Web semble brisée. Par conséquent, je ne peux pas utiliser la requête de support d’orientation de CSS3 pour appliquer des styles en fonction de l’orientation (à moins qu’il y ait une meilleure requête multimédia pour l’orientation de la cible). Voici un violon http://jsfiddle.net/hossain/S5nYP/5/ qui émule ceci – pour les tests de périphériques, utilisez la page de test complète – http://jsfiddle.net/S5nYP/embedded/result/

Voici une capture d’écran du comportement pris sur la page de démonstration. entrer la description de l'image ici

Donc, existe-t-il une alternative à ce problème, je suis ouvert à la solution basée sur JavaScript si la solution native CSS ne fonctionne pas.

J’ai trouvé un extrait sur http://davidbcalhoun.com/2010/dealing-with-device-orientation qui suggère d’append la classe et la cible en fonction de cela. Par exemple:

   

Element Heading - Landscape

Element Heading - Portrait

Je sais que c’est avec quelques années de retard mais j’ai trouvé une excellente solution

Pour les médias de paysage:

 @media screen and (min-aspect-ratio: 13/9) { /* landscape styles here */} 

Et pour les médias de portrait:

 @media screen and (max-aspect-ratio: 13/9) { /* portrait styles here */} 

La solution complète et pourquoi cela fonctionne peut être trouvée ici Michael Barret – Défis du navigateur Android

Le problème réside dans la manière dont l’orientation est calculée:

http://www.w3.org/TR/css3-mediaqueries/#orientation

La fonction de média ‘orientation’ est ‘portrait’ lorsque la valeur de la fonctionnalité de média ‘height’ est supérieure ou égale à la valeur de la fonctionnalité de média ‘width’. Sinon, «orientation» est «paysage».

Étant donné que la hauteur / largeur est calculée dans la fenêtre visible, le clavier logiciel semble inverser l’orientation maintenant que la largeur de la fenêtre d’affichage est inférieure à la hauteur. Une solution consisterait simplement à utiliser vos requêtes multimédia en fonction de la width . Cela le rend plus flexible sur tous les appareils, quelle que soit leur orientation, sans parler de la largeur / hauteur, qui est plus largement supscope que l’orientation.

Si vous souhaitez comptabiliser la largeur au lieu de l’orientation, j’utiliserai l’iPhone comme exemple:

 @media screen and (max-width: 320px) { /* rules applying to portrait */ } @media screen and (max-width: 480px) { /* rules applying to landscape */ } 

Cette approche est plus souple que l’orientation, car les requêtes ne sont pas limitées aux périphériques / agents utilisateurs qui prennent en charge l’orientation, sans compter que l’orientation indique très peu par rapport à la largeur.

Bien sûr, si vous avez vraiment besoin de connaître l’orientation, il semble que vous devez définir la classe au départ et utiliser simplement cette option.

Une alternative pourrait être d’utiliser le device-aspect-ratio , qui rest inchangé. Toutefois, dans Webkit, la rotation de l’appareil ne déclenche pas une mise à jour des règles CSS à l’aide de cette requête, même si les tests JavaScript sont renvoyés à la valeur réelle pour le nouveau format. Ceci est apparemment dû à un bogue , mais je ne suis pas en mesure de trouver un rapport de bogue. En combinant l’ orientation et le {min,max}-device-aspect-ratio semble fonctionner correctement:

 @media screen and (max-device-aspect-ratio: 1/1) and (orientation: portrait) @media screen and (min-device-aspect-ratio: 1/1) and (orientation: landscape) 

L’utilisation de l’ orientation déclenche les mises à jour comme prévu, et l’utilisation du device-aspect-ratio de device-aspect-ratio limite la mise à jour aux changements réels d’orientation.

J’ai travaillé sur les options énumérées ci-dessus et aucun n’a résolu les problèmes pour moi. Je suis passé à l’utilisation de screen.availHeight car il donne des résultats de hauteur cohérents évitant le problème d’affichage du clavier.

 // Avoiding the keyboard in Android causing the portrait orientation to change to landscape. // Not an issue in IOS. Can use window.orientation. var currentOrientation = function() { // Use screen.availHeight as screen height doesn't change when keyboard displays. if(screen.availHeight > screen.availWidth){ $("html").addClass('portrait').removeClass('landscape'); } else { $("html").addClass('landscape').removeClass('portrait'); } } // Set orientation on initiliasation currentOrientation(); // Reset orientation each time window is resized. Keyboard opening, or change in orientation sortingggers this. $(window).on("resize", currentOrientation); 

J’ai parcouru plusieurs des réponses ci-dessus et aucun d’entre eux n’a fait exactement ce que je voulais, à savoir imiter au mieux les fonctionnalités de l’iPhone. Ce qui suit est ce qui fonctionne pour moi dans la production maintenant.

Cela fonctionne en atsortingbuant la largeur et la hauteur de la fenêtre de la fenêtre de périphérique à un atsortingbut de données pour vérification ultérieure. Étant donné que les téléphones ne redimensionnent pas la largeur lorsque vous tirez sur le clavier, seule la hauteur, la vérification du rapport ET la largeur par rapport à la largeur d’origine peuvent vous indiquer si le clavier est actif. Je n’ai pas encore trouvé de cas d’utilisation qui a échoué, mais je suis sûr que oui. Si vous en trouvez tous un, faites-le moi savoir.

J’utilise certains globaux, comme InitialRun et MobileOrientation, qui sont utilisés pour le changement de js, j’utilise également les atsortingbuts de données html5 pour stocker des informations dans le DOM pour la manipulation de CSS.

  var InitialRun = true; // After the initial bootstrapping, this is set to false; var MobileOrientation = 'desktop'; function checkOrientation(winW, winH){ // winW and winH are the window's width and hieght, respectively if (InitialRun){ if (winW > winH){ $('body').attr('data-height',winW); $('body').attr('data-width',winH); MobileOrientation = 'landscape'; $('body').attr('data-orientation','landscape'); } else{ $('body').attr('data-height',winH); $('body').attr('data-width',winW); MobileOrientation = 'portrait'; $('body').attr('data-orientation','portrait'); } } else{ if (winW > winH && winW != $('body').data('width')){ MobileOrientation = 'landscape'; $('body').hdata('orientation','landscape'); //TODO:uncomment $('body, #wrapper').css({'height':"100%",'overflow-y':'hidden'}); //$('body').attr('data-orientation','portrait'); } else{ MobileOrientation = 'portrait'; $('body').attr('data-orientation','portrait'); $('body, #wrapper').css({'height':$('body').data('height'),'overflow-y':'auto'}); } } } 

Pour moi, cela a fait l’affaire:

  @media screen and (max-device-aspect-ratio: 1/1), (max-aspect-ratio: 1/1){ /*Portrait Mode*/ }; 

Alors que le max-aspect-ratio prend en charge le déclenchement du mode Portrait simplement en redimensionnant la fenêtre (utile pour les PC et autres périphériques ne contenant que du paysage), le max-device-aspect-ratio aide les smartphones ou autres appareils à orientation variable. Et comme je ne déclare pas de parameters spécifiques pour le mode Paysage, même si le max-aspect-ratio est supérieur à 1 pour le système, le mode Portrait sera toujours déclenché par max-device-aspect-ratio si le périphérique Android est orienté de cette manière. .

La partie 1/1 signifie essentiellement que si le rapport est <= 1, il passe en mode portrait, sinon il passe en mode paysage.

Jetez un oeil à ce lien: http://www.alistapart.com/articles/a-pixel-identity-crisis/
Le recours non seulement à l’orientation, mais également à la max-device-height ou au device-pixel-ratio peut aider. Quoi qu’il en soit, je ne l’ai pas testé, alors je ne suis pas sûr que cela vous aidera.

Idée: Supprimez le paramètre portrait de votre requête multimédia et laissez-le uniquement avec une largeur minimale. Faites votre style habituel pour le mode portrait dans cette requête multimédia. Ensuite, créez une autre requête multimédia pour le mode paysage avec une hauteur minimum suffisante pour que le navigateur n’utilise pas cette requête lorsque le clavier apparaît. Vous devriez expérimenter ce qu’est cette «hauteur minimum assez grande», mais cela ne devrait pas être trop difficile puisque la plupart des modes paysage (sinon tous) ont une hauteur supérieure à celle d’un clavier. De plus, vous pouvez append un «min-width» à la requête paysage qui est plus grand que la plupart des smartphones en mode portrait (environ ~ 400 pixels) pour limiter la scope de la requête.

Voici une solution alternative (et ténue): – Ajoutez un élément arbitraire vide à votre fichier HTML qui aura «affichage: aucun» dans un autre mode que le mode portrait. – Créez un écouteur jquery ou javascript pour l’entrée: focus. Lorsque vous cliquez sur une entrée, votre javascript vérifie la propriété d’affichage de l’élément arbitraire. S’il renvoie «block» ou ce que vous avez défini en mode portrait, vous pouvez remplacer votre style par JS dans vos requêtes en mode portrait. Inversement, vous auriez une entrée: blur listener pour effacer les propriétés style.cssText des éléments que vous avez codés en dur.

J’expérimente cela moi-même en ce moment – je posterai le code de ce qui fonctionne quand je reçois quelque chose de solide et gérable. (Ma première solution semble la plus raisonnable).

Cela fonctionne de manière fiable pour moi. J’utilise http://detectmobilebrowsers.com/ pour que l’extension jQuery détecte $ .browser.mobile.

 if ($.browser.mobile) { var newOrientationPortrait = true; //Set orientation based on height/width by default if ($(window).width() < $(window).height()) newOrientationPortrait = true; else newOrientationPortrait = false; //Overwrite orientation if mobile browser supports window.orientation if (window.orientation != null) if (window.orientation === 0) newOrientationPortrait = true; else newOrientationPortrait = false; 

Voici mon code pour modifier la fenêtre en fonction de l'orientation. Cette fonction est uniquement appelée pour les appareils mobiles, même pas pour les tablettes. Cela me permet d'écrire facilement des CSS pour 400px et 800px (Portrait vs Landscape).

 _onOrientationChange = function() { if (_orientationPortrait) $("meta[name=viewport]").attr("content", "width=400,user-scalable=no"); else $("meta[name=viewport]").attr("content", "width=800"); } 

En raison de la nature de mes besoins, je n’ai pas pu le faire dans les requêtes CSS Media uniquement, car le DOM lui-même devait changer en fonction de son orientation. Malheureusement, à mon travail, les entresockets écrivent des exigences logicielles sans consulter au préalable le développement.

J’ai rencontré exactement le même problème sur iPad.
c’est à dire; Lorsque le clavier tactile apparaît en mode portrait, le périphérique est détecté en orientation paysage et les styles de paysage sont appliqués à l’écran, ce qui entraîne une vue décousue.

Spécification du dispositif

  • Appareil : iPad Mini 4
  • OS : iOS 11.2.6
  • Résolution d’écran : 1024 x 768

Malheureusement, pour moi, cette solution n’a pas fonctionné.

 @media screen and (min-aspect-ratio: 13/9) { /* landscape styles here */} @media screen and (max-aspect-ratio: 13/9) { /* portrait styles here */} 

Donc, ce que j’ai fait, c’est que j’ai écrit une requête média comme celle-ci pour mon mode portrait.

 @media only screen and (min-width : 300px) and (max-width : 768px) and (orientation : landscape) { /* portrait styles, when softkeyboard appears, goes here */ } 

c’est à dire; Lorsque le clavier tactile apparaît, la hauteur de l’écran diminue, mais la largeur de l’écran rest à 768 pixels, ce qui entraîne l’affichage de l’écran de détection de requête multimédia en mode paysage. D’où le travail autour de nous donné ci-dessus.