Browser compatibility — viewports

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.

Definitions

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.

Viewport properties

This table looks into the properties that are necessary to read out useful information about the three viewports and the two types of pixels.

Test page.

iOS iOS WebView And. 4 AWK Web­View Chromium Chromium WebView UC 11 Black­Berry 10 Dol­phin Opera Mini IE 11 Edge 14 Fire­fox 49
9 10 9 10 LG Cy HTC S34 MM S44 Xia Op Ub Go 30 33 39 45 54 11 19
screen.width and screen.height

Dimensions of the ideal layout viewport.

Por­trait Phy­sical Yes Yes Phy­sical Yes Phy­sical Yes Yes Lay­out Yes

screen.width should return the dimensions of the ideal viewport. The older implementation returns the number of physical device pixels, but that’s now seen as wrong.

Physical
Gives the physical screen dimensions.
Portrait
Always gives the portrait values even when in landscape.
Layout
Gives the layout viewport dimensions, except that the toolbars are counted as well.
window.innerWidth and window.innerHeight

Dimensions of the visual viewport in CSS pixels.

Yes Yes Yes Yes Yes No Yes
iOS iOS WebView And. 4 AWK Web­View Chromium Chromium WebView UC 11 Black­Berry 10 Dol­phin Opera Mini IE 11 Edge 14 Fire­fox 49
9 10 9 10 LG Cy HTC S34 MM S44 Xia Op Ub Go 30 33 39 45 54 11 19
documentElement. clientWidth and documentElement. clientHeight

Dimensions of the layout viewport in CSS pixels.

Yes Yes inner Yes Yes Yes Yes
inner
Equal to 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

window.scrollX/Y gives exactly the same values. I think we should change one of them to the scrolling offset of the layout viewport.

Mouse/touch coordinates

Test page.

iOS iOS WebView And. 4 AWK Web­View Chromium Chromium WebView UC 11 Black­Berry 10 Dol­phin Opera Mini IE 11 Edge 14 Fire­fox 49
9 10 9 10 LG Cy HTC S34 MM S44 Xia Op Ub Go 30 33 39 45 54 11 19
clientX/Y

In CSS pixels, relative to the visual viewport

Yes Yes Yes Layout Yes L Yes Untest­able 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 window.pageX/YOffset is equal to -getBounding().left/top, and the coordinates relative to the layout and visual viewport seem to be the same. (In fact, the document element’s offset is calculated relative to the visual 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 clientX/Y relative to the visual viewport.

See this app for a visualisation of the modern layout viewport.

Layout or L
Relative to the layout viewport. New definition.
pageX/Y

In CSS pixels, relative to the document

Yes Yes Yes Yes Yes Untest­able Yes
screenX/Y

In CSS pixels, relative to the screen.

Don’t use
page client 0 Yes client Yes 0 Yes client phy­sical client Untest­able Incor­rect client
screenX/Y = (pageX/Y - window.pageX/YOffset) * 
(document.documentElement.clientWidth/Height / window.innerWidth/Height) - toolbarOffset toolbarOffset = screen.height - (window.innerHeight * (document.documentElement.clientWidth / window.innerWidth)

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 screen.height gives the wrong information in a few browsers. I’m working on that.

client
Equal to clientX/Y
page
Equal to pageX/Y
physical
In device pixels, relative to the visual viewport
  • I don’t understand IE11’s/Edge’s values.

getBoundingClientRect()

element.getBoundingClientRect().left/top returns the position of the element relative to the viewport. But WHICH viewport?

Test page.

iOS iOS WebView And. 4 AWK Web­View Chromium Chromium WebView UC 11 Black­Berry 10 Dol­phin Opera Mini IE 11 Edge 14 Fire­fox 49
9 10 9 10 LG Cy HTC S34 MM S44 Xia Op Ub Go 30 33 39 45 54 11 19
getBoundingClientRect().left/top

Position of the element relative to the visual viewport.

Yes Yes Yes Layout Yes Yes lay­out Yes l Yes
Layout or l
Relative to the layout viewport (which in Opera Mini equals the document)

Meta viewport

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.

Test page

iOS iOS WebView And. 4 AWK Web­View Chromium Chromium WebView UC 11 Black­Berry 10 Dol­phin Opera Mini IE 11 Edge 14 Fire­fox 49
9 10 9 10 LG Cy HTC S34 MM S44 Xia Op Ub Go 30 33 39 45 54 11 19
Basics

Sets the dimensions of the layout viewport.

Yes Yes Yes No Yes Yes

The Chromium WebViews always apply device-width, regardless of the content of the meta viewport tag — and even when it’s not there at all.
Firt told me it’s because native Android apps give you the opportunity to set the layout viewport size. Which kind-of makes sense, although the iOS WebView does support meta viewports normally.

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.document­Element.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.

Tested browsers

Mobile browser test array 3.2; September 2016

iOS 9
WebKit 601
Default browser on iPhone 4S with iOS 9.3.5
iOS 10
WebKit 601
Default browser on iPad Air 2 with iOS 10.0.2
iOS 9 WebView
WebKit 602
Chrome/iOS on iPhone 4S with iOS 9.3.5
iOS 10 WebView
WebKit 602
Chrome/iOS on iPad Air 2 with iOS 10.0.2
Android WebKit 4
WebKit 534
Default browser on Huawei C8813, Android 4.1.1
Default browser on Samsung Galaxy Note I, Android 4.1.2
Default browser on Sony Xperia S, Android 4.1.2
Default browser on LG L5, Android 4.1.2
Default browser on Wolfgang AT-AS45FW, Android 4.2.2 (see note below)
Default browser on HTC One X, Android 4.2.2
Android 4 WebView
WebKit 534
WebView on Samsung Galaxy Note I, Android 4.1.2
WebView on Sony Xperia S, Android 4.1.2
WebView on HTC One X, Android 4.2.2
WebView on Wolfgang AT-AS45FW, Android 4.2.2 (see note below)
All these WebViews were tested with the HTML5Test Android app.
Chromium LG 30
Blink; Chromium 30
Default browser on LG L70, Android 4.4.2
Chromium Cyanogen 33
Blink; Chromium 33
Default browser on Galaxy Nexus flashed with Cyanogenmod 11, Android 4.4.4
Chromium HTC 33
Blink; Chromium 33
Default browser on HTC M8, Android 6.0
Chromium Samsung 34
Blink; Chromium 34
Default browser on Samsung Galaxy S4, Android 5.0.1
Chromium Micromax 39
Blink; Chromium 39
Default browser on Micromax Canvas Nitro 3 Android 5.1
Chromium Samsung 44
Blink; Chromium 38
Default browser on Samsung Galaxy S6, Android 6.0.1
Chromium Xiaomi 46
Blink; Chromium 46
Default browser on Xiaomi M2, Android 5.0.2
Chromium Opera 50
Blink; Chromium 50
34 on LG L5, Android 4.1.2
Chromium Ubuntu 52
Blink; Chromium 52
Default browser on Ubuntu Phone 15.04
Chromium Google 53
Blink; Chromium 53
Default browser on Motorola Moto G, Android 5.1
This is Google’s regular Chrome. I test it only on devices where it is the default browser.
Chromium WebView 30
Blink; Chromium 30
WebView on LG L70, Android 4.4.2
All these WebViews were tested with the HTML5Test Android app.
Chromium WebView 33
Blink; Chromium 33
WebView on Galaxy Nexus flashed with Cyanogenmod 11, Android 4.4.4
Chromium WebView 39
Blink; Chromium 39
WebView on Micromax Canvas Nitro 3 Android 5.1
Chromium WebView 45
Blink; Chromium 45
WebView on HTC M8, Android 6.0
Chromium WebView 54
Blink; Chromium 54
WebView on Samsung Galaxy S6, Android 6.0.1
All these WebViews were tested with the HTML5Test Android app.
UC 11
WebKit 534
UC 11.0.5 on Samsung Galaxy S6, Android 6.0.1
BlackBerry 10
WebKit 537
Default browser on BlackBerry Z30 (BB OS 10.3.2)
Dolphin
Probably WebKit
Dolphin 11.5.7 with JetPack on Samsung Galaxy S4, Android 5.0.1
Independent full browser for Android, as long as you install both Dolphin and the Jetpack extension.
It claims to be a Chromium 33, but it lies.
Opera Mini 11
Presto
Proxy browser
11 on Intex Agua Super, Android 5.1. It is the default browser on this device; that’s why included this old version
Opera Mini 19
Presto
Proxy browser
19 on Motorola Moto G, Android 5.1
IE11
Trident
Default browser on Nokia Lumia 820, Windows Phone 8.1 “Update”
This is a developer phone. That might matter.

Edge 14
Edge
Default browser on Nokia Lumia 830, Windows 10 Mobile
Firefox Android
Gecko 49
47 on Motorola Moto G, Android 5.1