Lorsque vous restructurez ou développez des pages web sur des appareils mobiles, la première chose à bien comprendre est le viewport sur les appareils mobiles. Ce n'est qu'en comprenant le concept de viewport et en clarifiant l'utilisation de la balise meta liée au viewport que nous pouvons mieux nous adapter ou répondre aux appareils mobiles ayant diverses résolutions.
I. Le concept de viewport
En termes simples, le viewport sur un appareil mobile est la zone de l'écran de l'appareil qui peut être utilisée pour afficher notre page web. Plus précisément, il s'agit de la partie du navigateur (ou d'une webview dans une application) utilisée pour afficher la page web. Cependant, le viewport n'est pas limité à la taille de la zone visible du navigateur ; il peut être plus grand ou plus petit que la zone visible du navigateur. Par défaut, d'une manière générale, le viewport sur un appareil mobile est plus grand que la zone visible du navigateur. Cela est dû au fait que la résolution des appareils mobiles est relativement faible par rapport aux ordinateurs de bureau. Par conséquent, afin d'afficher correctement les sites web traditionnels conçus pour les navigateurs de bureau sur les appareils mobiles, les navigateurs des appareils mobiles définissent leur viewport par défaut sur 980px ou 1024px (ou d'autres valeurs, déterminées par l'appareil lui-même). Mais la conséquence est que le navigateur aura une barre de défilement horizontale, car la largeur de la zone visible du navigateur est inférieure à la largeur de ce viewport par défaut. La figure suivante répertorie les largeurs de viewport par défaut des navigateurs sur certains appareils.

II. 1px en CSS n'est pas égal à 1px de l'appareil
En CSS, nous utilisons généralement px comme unité. Dans les navigateurs de bureau, 1 pixel CSS correspond souvent à 1 pixel physique de l'écran de l'ordinateur. Cela peut créer l'illusion que les pixels en CSS sont les pixels physiques de l'appareil. Mais la situation réelle n'est pas ainsi. Les pixels en CSS ne sont qu'une unité abstraite. Sur différents appareils ou dans différents environnements, les pixels physiques de l'appareil représentés par 1px en CSS sont différents. Dans les pages web conçues pour les navigateurs de bureau, nous n'avons pas besoin de nous en préoccuper, mais sur les appareils mobiles, nous devons comprendre ce point. Dans les premiers appareils mobiles, la densité de pixels de l'écran était relativement faible, comme l'iPhone 3, dont la résolution était de 320x480. Sur l'iPhone 3, un pixel CSS était en effet égal à un pixel physique de l'écran. Plus tard, avec le développement de la technologie, la densité de pixels des écrans des appareils mobiles est devenue de plus en plus élevée. À partir de l'iPhone 4, Apple a lancé l'écran dit Retina, avec une résolution doublée à 640x960, mais la taille de l'écran n'a pas changé. Cela signifie que sur un écran de même taille, il y a deux fois plus de pixels. À ce moment-là, un pixel CSS est égal à deux pixels physiques. Il en va de même pour les appareils mobiles d'autres marques. Par exemple, les appareils Android peuvent être divisés en différents niveaux tels que ldpi, mdpi, hdpi, xhdpi selon la densité de pixels de l'écran, et les résolutions sont également diverses. Le nombre de pixels physiques d'écran auxquels un pixel CSS correspond sur un appareil Android varie aussi d'un appareil à l'autre, et il n'existe pas de réponse définitive.
Un autre facteur qui provoque également des changements de px en CSS est la mise à l'échelle par l'utilisateur. Par exemple, lorsque l'utilisateur agrandit la page de 100 %, les pixels physiques représentés par 1px en CSS doubleront également ; inversement, lorsque la page est réduite de moitié, les pixels physiques représentés par 1px en CSS seront également réduits de moitié. Ce point sera abordé plus loin dans l'article.
Dans les navigateurs mobiles et certains navigateurs de bureau, l'objet window possède une propriété devicePixelRatio. Sa définition officielle est : le rapport entre les pixels physiques de l'appareil et les pixels indépendants de l'appareil, c'est-à-dire devicePixelRatio = pixels physiques / pixels indépendants. Le px en CSS peut être considéré comme le pixel indépendant de l'appareil, donc grâce à devicePixelRatio, nous pouvons savoir combien de pixels physiques un pixel CSS représente sur cet appareil. Par exemple, sur un iPhone à écran Retina, la valeur de devicePixelRatio est 2, ce qui signifie que 1 pixel CSS équivaut à 2 pixels physiques. Cependant, il faut noter que devicePixelRatio a encore quelques problèmes de compatibilité dans différents navigateurs, donc nous ne pouvons pas nous y fier entièrement pour l'instant. Pour des situations spécifiques, vous pouvez regardercet article。
Résultats des tests de devicePixelRatio:

III. La théorie de PPK sur les trois viewports
Le grand ppka fait beaucoup de recherches sur le viewport sur les appareils mobiles (Premier article,Deuxième article,Troisième article), les étudiants intéressés peuvent y jeter un coup d'œil. Bon nombre des données et points de vue de cet article proviennent également de là. ppk pense qu'il y a trois viewports sur les appareils mobiles.
Tout d'abord, le navigateur sur un appareil mobile estime qu'il doit permettre à tous les sites web de s'afficher normalement, même ceux qui ne sont pas conçus pour les appareils mobiles. Mais si la zone visible du navigateur est utilisée comme viewport, parce que les écrans des appareils mobiles ne sont pas très larges, les sites web conçus pour les navigateurs de bureau, lorsqu'ils sont affichés sur des appareils mobiles, seront inévitablement compressés parce que le viewport est trop étroit, et même la mise en page peut être perturbée. Peut-être quelqu'un demandera-t-il : n'y a-t-il pas aujourd'hui beaucoup de téléphones avec de très grandes résolutions, comme 768x1024, ou 1080x1920 ? De tels téléphones devraient pouvoir afficher sans problème des sites web conçus pour les navigateurs de bureau, non ? Comme nous l'avons dit plus tôt, 1px en CSS ne représente pas 1px à l'écran. Plus votre résolution est grande, plus 1px en CSS représente de pixels physiques, et plus la valeur de devicePixelRatio est grande. C'est facile à comprendre, car votre résolution a augmenté, mais la taille de l'écran n'a pas beaucoup augmenté. Vous devez faire en sorte que 1px en CSS représente davantage de pixels physiques afin que la taille d'un objet de 1px à l'écran soit similaire à celle sur les appareils à faible résolution ; sinon, il sera trop petit pour être vu clairement. Donc, sur un appareil comme 1080x1920, par défaut, vous n'aurez peut-être besoin de définir la largeur d'une div que légèrement au-dessus de 300px (selon la valeur de devicePixelRatio) pour obtenir toute la largeur de l'écran. Revenons au sujet : si la zone visible du navigateur sur un appareil mobile est définie comme viewport, certains sites web s'afficheront incorrectement parce que le viewport est trop étroit. Par conséquent, ces navigateurs décident de définir le viewport sur une valeur plus large par défaut, comme 980px, afin que même les sites web conçus pour ordinateur de bureau puissent s'afficher normalement sur les navigateurs mobiles. ppk appelle ce viewport par défaut du navigateur le viewport de mise en page. La largeur de ce viewport de mise en page peut être obtenue via document.documentElement.clientWidth.
Cependant, la largeur du viewport de mise en page est supérieure à la largeur de la zone visible du navigateur, nous avons donc aussi besoin d’un viewport pour représenter la taille de la zone visible du navigateur. ppk appelle ce viewport le viewport visuel. La largeur du viewport visuel peut être obtenue via window.innerWidth, mais elle ne peut pas être obtenue correctement dans Android 2, Opera Mini et UC 8.


Maintenant, nous avons déjà deux viewports : le viewport de mise en page et le viewport visuel. Mais le navigateur estime que ce n’est pas suffisant, car de plus en plus de sites web sont conçus séparément pour les appareils mobiles, il doit donc aussi exister un viewport qui puisse parfaitement s’adapter aux appareils mobiles. L’adaptation parfaite en question signifie : premièrement, sans nécessiter de zoom de l’utilisateur ni de défilement horizontal, vous pouvez consulter normalement tout le contenu du site web ; deuxièmement, la taille du texte affiché est appropriée. Par exemple, un paragraphe de texte de 14px ne sera pas trop petit pour être lu clairement sur un écran à pixels haute densité. Idéalement, quelle que soit la densité d’écran ou la résolution, la taille de ce texte de 14px devrait être à peu près la même. Bien sûr, pas seulement le texte, mais aussi d’autres éléments tels que les images suivent le même principe. ppk appelle ce viewport le viewport idéal, qui est le troisième viewport - le viewport idéal des appareils mobiles.
Le viewport idéal n’a pas de taille fixe ; différents appareils ont différents viewports idéaux. Tous les iPhone ont une largeur de viewport idéale de 320px, que leur largeur d’écran soit 320 ou 640. Autrement dit, dans l’iPhone, 320px en CSS représente la largeur de l’écran de l’iPhone.


Mais les appareils Android sont plus compliqués. Il y a 320px, 360px, 384px, etc. Quant à la largeur de viewport idéale des différents appareils, vous pouvez aller surhttp://viewportsizes.compour y jeter un œil ; il recense les largeurs idéales de nombreux appareils.
Pour résumer à nouveau :ppk divise le viewport sur les appareils mobiles en trois types : viewport de mise en page, viewport visuel et viewport idéal. Parmi eux, le viewport idéal est le viewport le plus approprié pour les appareils mobiles. La largeur du viewport idéal est égale à la largeur d'écran de l'appareil mobile. Tant que vous définissez la largeur d'un élément en CSS sur la largeur du viewport idéal (en px), la largeur de l'élément sera la largeur d'écran de l'appareil, c'est-à-dire l'effet d'une largeur de 100 %. L'importance du viewport idéal est que, quelle que soit la résolution de l'écran, les sites web conçus pour le viewport idéal peuvent être présentés parfaitement aux utilisateurs sans nécessiter de zoom manuel ni de barres de défilement horizontales.
IV. Utilisation de la balise meta pour contrôler le viewport
Le viewport par défaut sur les appareils mobiles est le viewport de mise en page, qui est plus large que l'écran. Mais lors du développement de sites web pour appareils mobiles, nous avons besoin du viewport idéal. Alors, comment obtenir le viewport idéal ? C'est là que la balise meta entre en jeu.
Lors du développement de sites web mobiles, l'une des actions les plus courantes consiste à copier ce qui suit dans notre balise head :
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
Cette balise meta fait que la largeur du viewport actuel est égale à la largeur de l'appareil, tout en empêchant également l'utilisateur de zoomer manuellement. Différents sites web peuvent avoir des exigences différentes quant à savoir si le zoom est autorisé, mais faire en sorte que la largeur du viewport soit égale à la largeur de l'appareil est probablement un effet que tout le monde souhaite. Si vous ne le définissez pas ainsi, le viewport par défaut plus large que l'écran sera utilisé, ce qui signifie qu'une barre de défilement horizontale apparaîtra.
Que contient exactement cette balise meta avec name="viewport", et que fait chacune de ses parties ?
La balise meta viewport a été introduite pour la première fois par Apple dans son navigateur Safari pour résoudre le problème du viewport sur les appareils mobiles. Plus tard, Android et les principaux fournisseurs de navigateurs ont suivi le mouvement et ajouté la prise en charge de meta viewport, et cela s'est avéré très utile.
Dans la spécification d'Apple, meta viewport possède 6 attributs (appelons pour l'instant les éléments dans content des attributs et des valeurs), comme suit :
| width | Définit width duviewport de mise en page, un entier positif ou la chaîne "width-device" |
| initial-scale | Définit la valeur de zoom initiale de la page, un nombre qui peut être décimal. |
| minimum-scale | La valeur de zoom minimale autorisée pour l'utilisateur, un nombre qui peut être décimal. |
| maximum-scale | La valeur de zoom maximale autorisée pour l'utilisateur, un nombre qui peut être décimal. |
| height | Définit height duviewport de mise en page, cet attribut n'est pas important pour nous et est rarement utilisé. |
| user-scalable | Indique si l'utilisateur est autorisé à zoomer, la valeur est "no" ou "yes" ; no signifie non autorisé, yes signifie autorisé. |
Ces attributs peuvent être utilisés simultanément, individuellement ou en combinaison. Lorsque vous utilisez plusieurs attributs en même temps, séparez-les simplement par des virgules.
De plus, Android prend également en charge la propriété privée target-densitydpi, qui indique le niveau de densité de l'appareil cible et détermine combien de pixels physiques représente 1px en CSS.
| target-densitydpi | La valeur peut être un nombre ou l'une des chaînes high-dpi, medium-dpi, low-dpi, device-dpi. |
Notez en particulier que lorsque target-densitydpi=device-dpi, 1px en CSS équivaut à 1 pixel physique.
Parce que cette propriété n'est prise en charge que par Android, et qu'Android a décidé de la dépréciertarget-densitydpicette propriété, nous devrions éviter de l'utiliser.
V. Réglage de la largeur du viewport actuel sur la largeur idéale du viewport
Pour obtenir le viewport idéal, vous devez définir la largeur du viewport de mise en page par défaut sur la largeur d'écran de l'appareil mobile. Comme width dans le meta viewport peut contrôler la largeur du viewport de mise en page, nous avons seulement besoin de définir width sur la valeur spéciale width-device.
<meta name="viewport" content="width=device-width">
La figure suivante montre les résultats de test de cette ligne de code dans les principaux navigateurs mobiles :

On peut voir qu'avec width=device-width, tous les navigateurs peuvent transformer la largeur du viewport actuel en largeur idéale du viewport. Cependant, notez que sur iPhone et iPad, que ce soit en portrait ou en paysage, la largeur est la largeur idéale du viewport en mode portrait.
Cette approche ressemble à quelque chose que tout le monde peut faire — même si vous n'avez jamais mangé de porc, vous avez sûrement déjà vu un cochon courir. En effet, lors du développement de pages web pour appareils mobiles, que vous compreniez ou non ce qu'est le viewport, cette ligne de code peut être tout ce dont vous avez besoin.
Mais vous ne savez probablement pas que
<meta name="viewport" content="initial-scale=1">
cette ligne de code peut également produire le même effet que la précédente, transformant le viewport actuel en viewport idéal.
Ha, surpris ? Parce que, théoriquement, cette ligne de code empêche seulement la page actuelle d'être zoomée, ce qui signifie que la page reste à sa taille naturelle. Alors pourquoi a-t-elle le même effet que width=device-width ?
Pour comprendre cela, vous devez d'abord déterminer à quoi le zoom est relatif. Étant donné que la valeur de zoom ici est 1, c'est-à-dire aucun zoom, et qu'il produit pourtant l'effet de viewport idéal, il ne peut y avoir qu'une seule réponse : le zoom est relatif au viewport idéal. Lorsque le viewport idéal est zoomé à 100 %, c'est-à-dire une valeur de zoom de 1, n'obtient-on pas le viewport idéal ? En pratique, c'est bien le cas. La figure suivante montre les résultats des tests dans les principaux navigateurs mobiles lors du réglage desi <meta name="viewport" content="initial-scale=1"> peut transformer la largeur du viewport actuel en largeur du viewport idéal.

Les résultats des tests montrent que initial-scale=1 peut également transformer la largeur du viewport actuel en largeur du viewport idéal. Mais cette fois, IE sur Windows Phone définit la largeur sur celle du viewport idéal en mode portrait, indépendamment du fait qu'il soit en portrait ou en paysage. Cependant, ce petit défaut n'a plus d'importance.
Mais que se passe-t-il si width et initial-scale=1 apparaissent ensemble et entrent en conflit ? Par exemple :
<meta name="viewport" content="width=400, initial-scale=1">
width=400 signifie définir la largeur du viewport actuel à 400px, tandis que initial-scale=1 signifie définir la largeur du viewport actuel à la largeur du viewport idéal. Alors, quelle instruction le navigateur doit-il suivre ? Celle écrite plus tard ? Non. Dans ce cas, le navigateur prend la plus grande des deux valeurs. Par exemple, lorsque width=400 et que la largeur du viewport idéal est de 320, il prend 400 ; lorsque width=400 et que la largeur du viewport idéal est de 480, il prend la largeur du viewport idéal. (Remarque : dans le navigateur UC9, lorsque initial-scale=1, quelle que soit la valeur de l'attribut width, la largeur du viewport est toujours celle du viewport idéal.)
Enfin, pour résumer : pour définir la largeur du viewport actuel sur la largeur du viewport idéal, vous pouvez utiliser soit width=device-width, soit initial-scale=1, mais chacun a un petit défaut : iPhone, iPad et IE ne distinguent pas les orientations portrait et paysage, et utilisent toujours la largeur du viewport idéal en portrait. Par conséquent, l'approche la plus parfaite consiste à écrire les deux ensemble. Ainsi, initial-scale=1 résout le problème iPhone/iPad, et width=device-width résout le problème IE :
<meta name="viewport" content="width=device-width, initial-scale=1">
VI. Plus de connaissances sur le meta viewport
1. À propos de la mise à l'échelle et de la valeur par défaut de initial-scale
Tout d'abord, parlons de la question du zoom. Comme mentionné précédemment, le zoom est relatif au viewport idéal. Plus la valeur de zoom est grande, plus la largeur du viewport actuel est petite, et inversement. Par exemple, sur iPhone, la largeur du viewport idéal est de 320px. Si nous définissons initial-scale=2, la largeur du viewport ne devient que 160px. C'est facile à comprendre : en zoomant de 1x, le 1px d'origine devient 2px. Mais le fait que 1px devienne 2px ne signifie pas que les 320px d'origine deviennent 640px ; au contraire, la largeur réelle restant inchangée, 1px devient la même longueur que les 2px d'origine. Ainsi, après un zoom de 2x, une largeur qui nécessitait auparavant 320px pour être remplie ne nécessite plus que 160px. Par conséquent, nous pouvons en déduire une formule :
visual viewport宽度 = ideal viewport宽度 / 当前缩放值 当前缩放值 = ideal viewport宽度 / visual viewport宽度
ps:La largeur du viewport visuel désigne la largeur de la zone visible du navigateur.
La plupart des navigateurs sont conformes à cette théorie, mais les navigateurs natifs sous Android et IE rencontrent quelques problèmes. Le navigateur WebKit intégré d'Android ne se comporte normalement que lorsque initial-scale=1 et qu'aucun attribut width n'est défini, ce qui signifie que cette théorie ne s'applique pratiquement pas à lui. IE, en revanche, ignore complètement l'attribut initial-scale ; quelle que soit la valeur que vous lui donnez, initial-scale se comporte toujours comme 1.
Bon, maintenant parlons du problème de la valeur par défaut de initial-scale. C'est-à-dire, lorsque cet attribut n'est pas écrit, quelle sera sa valeur par défaut ? De toute évidence, ce ne sera pas 1, car lorsque initial-scale = 1, la largeur actuelle du viewport de mise en page sera définie sur la largeur du viewport idéal. Mais comme mentionné précédemment, les largeurs par défaut du viewport de mise en page dans les différents navigateurs sont généralement des valeurs comme 980, 1024, 800, etc. Aucun navigateur ne commence avec la largeur du viewport idéal, donc la valeur par défaut de initial-scale n'est certainement pas 1. Sur les appareils Android, la valeur par défaut de initial-scale semble ne pas pouvoir être obtenue, ou peut-être qu'elle n'a simplement pas de valeur par défaut ; elle ne prend effet que lorsque vous l'écrivez explicitement. Ne nous en préoccupons pas. Ici, nous nous concentrons sur la valeur par défaut de initial-scale sur iPhone et iPad.
D'après les tests, nous pouvons arriver à une conclusion sur iPhone et iPad : quelle que soit la largeur que vous définissez pour le viewport de mise en page, si vous ne spécifiez pas de valeur d'échelle initiale, iPhone et iPad calculeront automatiquement la valeur de initial-scale pour garantir que la largeur actuelle du viewport de mise en page soit la largeur de la zone visible du navigateur après mise à l'échelle, ce qui signifie qu'aucune barre de défilement horizontale n'apparaîtra. Par exemple, sur iPhone, si nous ne définissons aucune balise meta viewport, la largeur du viewport de mise en page est de 980px à ce moment-là, mais nous pouvons voir que le navigateur n'affiche pas de barre de défilement horizontale ; le navigateur réduit la page par défaut. D'après la formule ci-dessus,valeur d'échelle actuelle = largeur du viewport idéal / largeur du viewport visuel, nous pouvons conclure :
当前缩放值 = 320 / 980
C'est-à-dire que la valeur par défaut actuelle de initial-scale devrait être d'environ 0.33. Lorsque vous spécifiez une valeur pour initial-scale, cette valeur par défaut ne prend plus effet.
En bref, retenez simplement cette conclusion : sur iPhone et iPad, quelle que soit la largeur que vous définissez pour le viewport, si aucune valeur d'échelle par défaut n'est spécifiée, iPhone et iPad calculeront automatiquement cette valeur d'échelle afin d'empêcher l'apparition d'une barre de défilement horizontale sur la page actuelle (autrement dit, faire en sorte que la largeur du viewport soit égale à la largeur de l'écran).
2. Modifier dynamiquement la balise meta viewport
La première méthode
Vous pouvez utiliser document.write pour générer dynamiquement la balise meta viewport, par exemple :
document.write('<meta name="viewport" content="width=device-width,initial-scale=1">')
La deuxième méthode
La modifier via setAttribute
<meta id="testViewport" name="viewport" content="width = 380">
<script>
var mvp = document.getElementById('testViewport');
mvp.setAttribute('content','width=480');
</script>
Un bug dans le navigateur intégré d'Android 2.3
<meta name="viewport" content="width=device-width"> <script type="text/javascript"> alert(document.documentElement.clientWidth); //弹出600,正常情况应该弹出320 </script> <meta name="viewport" content="width=600"> <script type="text/javascript"> alert(document.documentElement.clientWidth); //弹出320,正常情况应该弹出600 </script>
La largeur idéale du viewport du téléphone testé est de 320px. La première valeur de la pop-up est 600, mais cette valeur devrait être le résultat de la deuxième ligne de balises meta ; ensuite, la deuxième valeur de la pop-up est 320, ce qui est l'effet obtenu par la première ligne de balises meta. Par conséquent, dans le navigateur intégré d'Android 2.3 (peut-être toutes les versions 2.x), remplacer ou modifier la balise meta viewport peut produire des résultats très déroutants.
VII. Conclusion
Après avoir dit autant de bêtises, il est encore nécessaire de résumer quelque chose d'utile à la fin.
Premièrement, si la balise meta viewport n'est pas définie, la valeur de largeur par défaut dans les navigateurs des appareils mobiles est 800px, 980px, 1024px, etc. En bref, elle est supérieure à la largeur de l'écran. L'unité px utilisée pour la largeur ici fait référence au px en CSS, ce qui n'est pas la même chose que le px représentant les pixels physiques réels de l'écran.
Deuxièmement, chaque navigateur d'appareil mobile a une largeur idéale. Cette largeur idéale désigne la largeur en CSS et n'a rien à voir avec la largeur physique de l'appareil. En CSS, cette largeur est équivalente à la largeur représentée par 100%. Nous pouvons utiliser la balise meta pour définir la largeur du viewport sur cette largeur idéale. Si vous ne connaissez pas la largeur idéale de cet appareil, vous pouvez utiliser la valeur spéciale device-width. En même temps, initial-scale=1 a également pour effet de définir la largeur du viewport sur la largeur idéale. Donc, nous pouvons utiliser
<meta name="viewport" content="width=device-width, initial-scale=1">
pour obtenir un viewport idéal (c'est-à-dire le viewport idéal mentionné précédemment).
Pourquoi avons-nous besoin d'un viewport idéal ? Par exemple, un téléphone avec une résolution de 320x480 a une largeur de viewport idéale de 320px, tandis qu'un autre téléphone avec la même taille d'écran mais une résolution de 640x960 a aussi une largeur de viewport idéale de 320px. Pourquoi la largeur idéale du téléphone avec une résolution plus élevée devrait-elle être identique à celle du téléphone avec une résolution inférieure ? C'est parce que ce n'est que de cette façon que le même site Web peut apparaître de manière identique ou similaire sur des appareils ayant des résolutions différentes. En fait, bien qu'il y ait tant de téléphones de types, marques et résolutions différents sur le marché, leurs largeurs de viewport idéales peuvent être résumées en seulement quelques valeurs comme 320, 360, 384, 400, etc., toutes très proches. Des largeurs idéales similaires signifient qu'un site Web conçu pour le viewport idéal d'un certain appareil ne se comportera pas très différemment, voire se comportera de la même manière, sur d'autres appareils.
Adresse originale : https://www.cnblogs.com/2050/p/3877280.html