Phaser3 fillscreen and position stuff on top, bottom,etc.

Use this html/css

<head>

        <title>Your title</title>

        <meta name="viewport" content="height=device-height, width=device-width, viewport-fit=cover, user-scalable=no">

        <meta name="apple-mobile-web-app-capable" content="yes">

        <meta name="mobile-web-app-capable" content="yes">

        <style>

            html, body {

                overflow: hidden;

                height: 100%;

                width: 100%;

                padding: 0;

                margin: 0;

            }

            body {

                background: #0f0069;

                display: block;

                touch-action: none;

                position: fixed;

            }

            </style>

        </style>

    </head>

This config

const config = {

    type: Phaser.AUTO,

    transparent: true,

    scale: {

        mode: Phaser.Scale.ENVELOP,

        autoCenter: Phaser.Scale.CENTER_BOTH,

        width: 1080,

        height: 1920

    },

    scene: scene

};

Create a scale variable outside all functions.
var scale;

On scene preload, add:

scene.scale.once('resize', function () {

        viewport = GetViewport();

        scale = (viewport.width/viewport.height)/(config.scale.width/config.scale.height);

        viewport = GetViewport(true);

    });

The GetViewport code:

const GetViewport = function (useInnerHeight = false) {

    const out = new Phaser.Geom.Rectangle();

    var scaleManager = scene.scale;

    var baseSize = scaleManager.baseSize;

    var canvasBounds = scaleManager.canvasBounds;

    var displayScale = scaleManager.displayScale;

    var parentSize = scaleManager.parentSize;

    var x = (canvasBounds.x >= 0) ? 0 : -(canvasBounds.x * displayScale.x);

    var y = (canvasBounds.y >= 0) ? 0 : -(canvasBounds.y * displayScale.y);

    var width;

    if (useInnerHeight) {

        if (window.innerWidth >= canvasBounds.width) {

            width = baseSize.width;

        } else {

            width = baseSize.width - (canvasBounds.width - window.innerWidth) * displayScale.x;

        }

    } else {

        if (parentSize.width >= canvasBounds.width) {

            width = baseSize.width;

        } else {

            width = baseSize.width - (canvasBounds.width - parentSize.width) * displayScale.x;

        }

    }

    var height;

    if (useInnerHeight) {

        if (window.innerHeight >= canvasBounds.height) {

            height = baseSize.height;

        } else {

            height = baseSize.height - (canvasBounds.height - window.innerHeight) * displayScale.y;

        }

    } else {

        if (parentSize.height >= canvasBounds.height) {

            height = baseSize.height;

        } else {

            height = baseSize.height - (canvasBounds.height - parentSize.height) * displayScale.y;

        }

    }

    out.setTo(x, y, width, height);

    return out;

}

Now if you use viewport.top, viewport.bottom, etc to position things on the screen, it will work on all browsers. And use .setScale(scale), so the relative size will look the same across browsers. Calling viewport = GetViewport(true); is only necessary because of Safari to get the positions correctly(but doesn’t affect other browsers so it’s fine).

Credits to rex for the GetViewport function. I just modified it a little.