58

Regarding window.innerWidth and document.documentElement.clientWidth,

  1. Webkit (Chrome / Safari) claims innerWidth is smaller than clientWidth.

  2. Trident and Presto claim innerWidth is bigger than clientWidth.

  3. Gecko claims innerWidth is the same size as clientWidth.

What is the correct behavior stated by W3C (or silimar "authority")?

Test Script (on JSFiddle) (on 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>

(Run the snippet in full page mode and un-maximize or "restore" the window. Observe debug_msg while dragging the edge of the window to resize it.)

Pacerier
  • 86,231
  • 106
  • 366
  • 634

3 Answers3

42

According to the W3C specification (17 March 2016):

The innerWidth attribute must return the viewport width including the size of a rendered scroll bar (if any), or zero if there is no viewport.

...

The clientWidth attribute must run these steps:

  1. If the element has no associated CSS layout box or if the CSS layout box is inline, return zero.
  2. If the element is the root element and the element's document is not in quirks mode, or if the element is the HTML body element and the element's document is in quirks mode, return the viewport width excluding the size of a rendered scroll bar (if any).
  3. Return the width of the padding edge excluding the width of any rendered scrollbar between the padding edge and the border edge, ignoring any transforms that apply to the element and its ancestors.
Community
  • 1
  • 1
approxiblue
  • 6,982
  • 16
  • 51
  • 59
  • 3
    This would be more useful if it explain the "why" about using one or the other the scenario the OP stated. – TetraDev Jan 22 '20 at 21:51
  • I just noticed that: Using iPad Web APP with `display: fullscreen`, when you are rotating viewpoint, these two values may be very different... Though there isn't any width for scrollbar in iPad Safari. – tsh Aug 29 '21 at 14:07
26

I am using this:

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

It covers cases where the scrollbar is not taken into consideration and has mobile support.

Magnus Lind Oxlund
  • 304
  • 1
  • 6
  • 19
mrgoos
  • 1,294
  • 14
  • 26
0

If you need to get the current, available viewport width, this code would help:

// Getting the available viewport width
const vw = Math.max(document.documentElement.clientWidth || 0, window.innerWidth || 0);
document.writeln(`The available viewport width is : ${vw}`);
Shayan
  • 21
  • 5
  • 1
    Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Jul 01 '23 at 14:25