Purpose of devicePixelRatio-based viewport adjustment in HTML5 wrapper?

Hi everyone, I have a question about a specific line in the default HTML5 wrapper.

if (typeof window.devicePixelRatio != 'undefined' && window.devicePixelRatio > 2) {
    var meta = document.getElementById("viewport");
    meta.setAttribute('content', 'width=device-width, initial-scale=' + (2 / window.devicePixelRatio) + ', user-scalable=no');
}

I fully understand what this code does from a technical standpoint, so no need to explain the semantics. However, I’m struggling to understand why it’s there and what specific problem it’s intended to solve.

In WebView environments like Telegram and Facebook Instant Games, this code actually causes layout issues — the rendered content doesn’t fit within the visible screen area. It appears zoomed-in and cropped, likely due to a mismatch between the adjusted initial-scale and how those WebViews handle devicePixelRatio.
Meanwhile, on desktop and mobile browsers (with devicePixelRatio 2.625 and 3.something), it doesn’t cause any issues.

Was this originally added to address a specific browser or device quirk?
And more importantly — is it safe to remove it today?

Thanks in advance for any insight or background you can share!

Linking to the relevant commits, for reference.

This exact code appears to have been introduced in the index.html here (back in 2014):

The first time that the value of initial-scale was adjusted based on devicePixelRatio appeared in this commit a few days earlier:

1 Like

It appears that the adjustment of initial-scale was simply to support high DPI screens, and it did not get added for a specific browser or device. The initial commit had an issue with BlackBerry Q10, apparently, but the use of devicePixelRatio remained after accounting for that.

It’s certainly possible that this code is no longer required. I have a suspicion that OpenFL’s scaling code internally has changed a lot since then, and this adjustment of initial-scale was intended more for how it behaved back then. However, I would need to dig deeper into that past code to figure out exactly how it worked (I was not involved with the OpenFL project at the time, and I would not even start using the library until years later).

1 Like

Here is OpenFL and Lime’s current code for scaling the HTML canvas element.

In particular, the canvas width and height accounts for the dimensions of the parent <div> multiplied by the scale (and scale is derived from devicePixelRatio). However, the canvas style.width and style.height are set to the dimensions of the parent <div> element only.

So basically, it renders at high quality for devicePixelRatio, but then gets scaled down to account for the behavior of px being device-independent pixels in CSS/HTML in browsers. This should be enough that initial-scale doesn’t need to be adjusted as long as the viewport width is set to device-width.


In the older OpenFL, it appears that every display object may have had its own canvas, including the stage. It appears that the stage’s canvas is the one actually displayed in the HTML DOM, and the others were drawn to it. This should make the stage’s canvas equivalent to the canvas used by HTML5Window in modern Lime.

This is the code that determines the initial width and height of the canvas. Basically, either the dimension of the parent <div> or the dimensions of the browser window.

And here’s the code that handles resizing:

It basically keeps the canvas width and height equal the the dimensions of the parent <div>.

Neither of these calculations of the canvas width and height account for devicePixelRatio or a similar scale variable derived from devicePixelRatio. The canvas style.width and style.height are not scaled down to account for devicePixelRatio either. In fact, it appears that devicePixelRatio wasn’t used anywhere in OpenFL at the time, except in that index.html template. So it appears that OpenFL didn’t even have a mode for rendering at a higher quality for HiDPI screens yet.


I think I’d still want to test without the initial-scale adjustment on some devices with various devicePixelRatio values, just to be extra careful. However, if there don’t appear to be any strange scaling issues, I would not be opposed to removing that initial-scale code from the index.html template in one of the next OpenFL updates.

2 Likes

Super helpful, @joshtynjala — that’s exactly the context I was looking for.
The game has been live with the default initial-scale override for some time now, and nobody has complained about scaling (with ~20K DAU).

Now that we’re preparing to publish on Telegram and Facebook, and I was surprised to see their WebViews behave differently. But once I removed the override, everything looked perfect there.

Next step is to test the version without the override in the already published environments.
They also use WebViews for mobile app container, so it’s a bit odd that the behavior differs.