Last major update on 16 October 2016.
Here’s the inevitable compatibility table that goes with my viewport research. It treats the viewports themselves as well as some related items.
position: fixed was moved to the CSS test pages.
See this blog post for my current viewport definitions, and A tale of two viewports for explanations of CSS and device pixels. See the visualisation for a clear idea of what the viewports are in modern browsers.
This table looks into the properties that are necessary to read out useful information about the three viewports and the two types of pixels.
|
screen.width and screen.height
Dimensions of the ideal layout viewport. |
Portrait | Physical | Yes | Yes | Physical | Yes | Physical | Yes | Yes | Layout | Yes | ||||||||||||||||||||||||||||
|
|
|||||||||||||||||||||||||||||||||||||||
|
window.innerWidth and window.innerHeight
Dimensions of the visual viewport in CSS pixels. |
Yes | Yes | Yes | Yes | Yes | No | Yes | ||||||||||||||||||||||||||||||||
|
documentElement. clientWidth and documentElement. clientHeight
Dimensions of the layout viewport in CSS pixels. |
Yes | Yes | inner | Yes | Yes | Yes | Yes | ||||||||||||||||||||||||||||||||
window.innerWidth/Height. |
|||||||||||||||||||||||||||||||||||||||
|
devicePixelRatio
Physical screen size divided by ideal layout viewport |
Yes | Yes | Yes | Yes | Yes | Yes | |||||||||||||||||||||||||||||||||
|
Opera Mini’s values are weird (2.1), but correct. |
|||||||||||||||||||||||||||||||||||||||
|
window.pageX/YOffset
The visual viewport’s scrolling offset relative to the document |
Yes | Yes | Yes | Yes | Yes | 0 | Yes | ||||||||||||||||||||||||||||||||
|
|
|||||||||||||||||||||||||||||||||||||||
|
clientX/Y
In CSS pixels, relative to the visual viewport |
Yes | Yes | Yes | Layout | Yes | L | Yes | Untestable | L | Yes | |||||||||||||||||||||||||||||
clientX/Y = pageX/Y - window.pageX/YOffset (visual) clientX/Y = pageX/Y + document.documentElement.getBoundingClientRect().left/top (layout) In browsers that don’t have a modern layout viewport Thus many browsers do not allow us to read out the position of the layout viewport because the layout viewport is equal to the top of the document. These browsers are counted as supporting See this app for a visualisation of the modern layout viewport. |
|||||||||||||||||||||||||||||||||||||||
|
pageX/Y
In CSS pixels, relative to the document |
Yes | Yes | Yes | Yes | Yes | Untestable | Yes | ||||||||||||||||||||||||||||||||
|
screenX/Y
In CSS pixels, relative to the screen. Don’t use |
page | client | 0 | Yes | client | Yes | 0 | Yes | client | physical | client | Untestable | Incorrect | client | |||||||||||||||||||||||||
screenX/Y = (pageX/Y - window.pageX/YOffset) * Toolbar offset is the offset of all toolbars, even though we should only count the top ones. Unfortunately I don’t think it’s possible to get the height of only the top ones. So this formula only works perfectly if the browser doesn’t have or removes the bottom toolbar. And
|
|||||||||||||||||||||||||||||||||||||||
element.getBoundingClientRect().left/top returns the position of the element relative to the viewport. But WHICH viewport?
Test pages for a regular element and for the documentElement.
|
getBoundingClientRect().left/top
Position of the element relative to the visual viewport. |
Yes | Yes | Yes | Layout | Yes | layout | Yes | layout | Yes | l | Yes | ||||||||||||||||||||||||||||
|
The layout definition will likely stay around, though I’m not sure what the other browsers will do. |
|||||||||||||||||||||||||||||||||||||||
Chrome added a visual viewport API, but not a layout viewport API. First made public in Chrome 61. Example:
window.visualViewport.width
|
offsetLeft/Top
Position of the visual viewport relative to the layout viewport. |
No | No | No | Yes | No | No | No | ||||||||||||||||||||||||||||||||
|
pageLeft/Top
Position of the visual viewport relative to the document. |
No | No | No | Yes | No | No | No | ||||||||||||||||||||||||||||||||
|
width/height
Dimensions of the visual viewport. |
No | No | No | Yes | No | No | No | ||||||||||||||||||||||||||||||||
|
scale
Zoom level of the visual viewport relative to the layout viewport. (1 = same size) |
No | No | No | Yes | No | No | No | ||||||||||||||||||||||||||||||||
Below you find a series of tests aimed at changing the width of the meta viewport after page load.
There’s also the main research page for the meta viewport, which gives a lot more details.
|
Basics
Sets the dimensions of the layout viewport. |
Yes | Yes | Yes | No | Yes | Yes | |||||||||||||||||||||||||||||||||
|
The Chromium WebViews always apply |
|||||||||||||||||||||||||||||||||||||||
|
Change immediately
Change the tag directly after it’s been written into the page |
Yes | Yes | See note | Yes | No | Yes | Yes | ||||||||||||||||||||||||||||||||
|
Change later
Change the tag once the page has been loaded |
Yes | Yes | See note | Yes | No | Yes | Yes | ||||||||||||||||||||||||||||||||
|
Remove
Remove the tag entirely |
No | No | No | No | No | No | |||||||||||||||||||||||||||||||||
Android WebKit WebView: It obeys the initial meta viewport (380px), but any change to the tag sets the layout viewport to the ideal values, even though window.innerWidth/Height and document.documentElement.clientWidth/Height show the values we just wrote into the meta viewport tag. So it’s very confused.
More importantly, this behaviour is different from the regular Android WebKit browser.