web-dev-qa-db-fra.com

window.innerWidth vs document.documentElement.clientWidth

En ce qui concerne window.innerWidth et document.documentElement.clientWidth,

  1. Webkit (Chrome/Safari) affirme que innerWidth est plus petit que clientWidth.

  2. Trident et Presto prétendent que innerWidth est plus grand que clientWidth.

  3. Gecko affirme que innerWidth est de la même taille que clientWidth.

Quel est le comportement correct déclaré par W3C (ou "autorité" de Silimar)?

Script de test ( sur JSFiddle ) (sur GoogleHost ):

setInterval(function() {
  var inner_w = window.innerWidth;
  var inner_h = window.innerHeight;
  var client_w = document.documentElement.clientWidth;
  var client_h = document.documentElement.clientHeight;
  var debug_msg = "inner: " + inner_w + "-" + inner_h + "<br>client: " + client_w + "-" + client_h;
  document.getElementById("d").innerHTML = debug_msg;
  document.title = debug_msg;
  document.body.style.background = (client_w === inner_w && client_h === inner_h ? "green" : "red");
}, 60);
<div id="d"></div>

(Exécutez l'extrait de code en mode pleine page et dé-maximisez ou "restaurez" la fenêtre. Observez debug_msg tout en faisant glisser le bord de la fenêtre pour la redimensionner.)

38
Pacerier

Selon le W3C spécification (17 mars 2016):

L'attribut innerWidth doit renvoyer la largeur de la fenêtre d'affichage, y compris la taille d'une barre de défilement rendue (le cas échéant), ou zéro s'il existe n'est pas une fenêtre.

...

L'attribut clientWidth doit exécuter ces étapes:

  1. Si l'élément n'a pas de zone de disposition CSS associée ou si la zone de disposition CSS est en ligne, retournez zéro.
  2. Si l'élément est l'élément racine et que le document de l'élément n'est pas en mode excentrique, ou si l'élément est l'élément corps HTML et que le document de l'élément est en mode excentrique, renvoyez la largeur de la fenêtre d'affichage à l'exclusion de la taille d'une barre de défilement rendue (le cas échéant). ).
  3. Renvoie la largeur du bord de remplissage à l'exclusion de la largeur de toute barre de défilement rendue entre le bord de remplissage et le bord de bordure, en ignorant toutes les transformations qui s'appliquent à l'élément et à ses ancêtres.
31
approxiblue

J'utilise ceci:

    window.innerWidth && document.documentElement.clientWidth ? 
Math.min(window.innerWidth, document.documentElement.clientWidth) : 
window.innerWidth || 
document.documentElement.clientWidth || 
document.getElementsByTagName('body')[0].clientWidth;

Il couvre les cas où la barre de défilement n'est pas prise en compte et dispose d'un support mobile.

17
mrgoos