Les largeurs en JavaScript et en CSS

Vous êtes-vous déjà heurtés aux différences d’interprétation de valeurs entre JavaScript et les media queries CSS, par exemple pour exécuter une action à très exactement 480px à la fois en JavaScript et en CSS ? … Et vous aussi, vous vous êtes arraché quelques cheveux ?

JavaScript propose moults opérations pour définir la largeur de votre périphérique ou de sa fenêtre :

  • screen.width
  • innerWidth
  • outerWidth
  • availWidth
  • clientWidth
  • device-width
  • etc.

De son côté, CSS permet également de cibler cette largeur via les Media Queries, par exemple avec @media (width: ...) ou @media (device-width: ...).

Eh ben vous savez quoi : aucune des solutions JavaScript ne renvoie à coup sûr la même valeur que CSS !

Tout cela dépendra de certaines intérprétations ou bugs de navigateurs, de leur version, de l’orientation du device, comme vous pouvez le constater dans l’illustration finale de ce billet.

Alors… comment faire ?

Quelques explications

Pour mieux comprendre pourquoi ce n’est pas aussi simple, je vous invite à consulter l’excellent billet First, understand your screen basé sur un tout aussi excellent (et complet) test du célèbre Peter-Paul Kock (ppk).

Ces deux articles sont certes longs mais hautement instructifs.

matchMedia() FTW !

Au final, la seul méthode qui me semble convenable pour avoir en JavaScript exactement la même valeur que celle renvoyée par les media queries CSS est la méthode JavaScript **matchMedia()**.

Le principe de cette « récente » méthode est simple : vous y placez tout simplement la chaîne de caractères correspondant exactement au Media Query souhaité. Et hopla.

Par exemple :

if (window.matchMedia("(min-width: 640px)").matches)
{
/* La largeur de fenêtre est au-moins 640px */
} else {
/* La largeur est inférieure à 640px */
}

Pour aller plus loin, enivrez-vous du superbe article de Rodolphe sur Alsacréations : La méthode matchMedia ou les Media Queries pour JavaScript.

Mon navigateur, il veut pas !

matchMedia est relativement récent et reconnu à partir de IE10 et Android 3. C’est la vie.

Si vous estimez cette compatibilité trop ténue, il est possible de vous tourner vers l’alternative MatchMedia polyfill, conçue par Scott Jehl, Paul Irish et Nicholas Zakas.

Bonus : comment connaître la valeur de mon viewport ?

Supposons que vous souhaitiez simplement connaître la valeur de la largeur de votre device en JavaScript.
La méthode matchMedia() ne vous renverra pas de valeur précise, mais uniquement un booléen « true / false ». Il faut alors se trourner vers d’autres outils.

Hop, un petit coup de Verge comblera vos souhaits !

Ce petit script déjoue les turpitudes, les bugs, et les différences d’interprétation des navigateurs mobiles.

Par exemple, la valeur renvoyée pour le Viewport (largeur de fenêtre) correspond exactement à ce que les Media Queries @media (width) et @media (height) renvoient.

Pour info, c’est ce script que j’emploie sur le site MyDevice.io.

Illustration

Ci-dessous : Nokia Lumia 1020 (WinPhone 8.0, IE10 mobile) en orientation paysage.

La bonne valeur est 480px… mais ce n’est pas le cas sur d’autres périphériques.
lumia

2 réflexions au sujet de « Les largeurs en JavaScript et en CSS »

  1. Effectivement, ce sujet est une bonne prise de tête. (Moi je n’ai plus de cheveux 🙂

    En attendant que la parc cible vire IE9 et inférieurs (pour le St Graal matchmedia), j’ai trouvé une méthode plutôt simple : baser la détection sur la CSS. Si je sais par exemple que le burger icon apparaît uniquement à partir de la media-query mobile d’après ma CSS, alors le JS basé dessus fera :

    if ($burger.css(‘display’) === ‘block’) {

    C’est pas parfait, mais ça marche, et l’avantage c’est que si je dois faire varier le déclenchement du breakpoint, pas besoin d’y revenir. ^^

  2. J’injecte via mon CSS des informations de ce type :

    body:after {
    display: none;
    }

    @media all and (max-width:30em) {
    body:after {
    content : ‘{« slider »:false}’;
    }
    }
    Je récupère cette config JSON avec JavaScript. Ce qui me permet d’exécuter tel ou tel action en fonction de ce que mon CSS injecte comme configuration.

Les commentaires sont fermés.