'CSS upscaling / force resolution

I'm working on a webgame and for performance reasons I'd like to render the UI at a certain resolution (lets say 640x480) and scale it up (just like you'd do with an image). Some transformations and background effects require quite some reflows/repaints, and for the experience its not really important to render these at a 4K resolution.

But I noticed that when I for example use scale(2) on a parent container, fonts, shadows and background gradiants are just rendered at a resolution x2 instead of rendering them at x1 and scale its result x2 (like im able to do with the contents of an canvas). I tried rendering it in an iframe and scaling this iframe x2, but still this results in the UI being rendered at x2 resolution.

Does anyone know of a way to achieve this?

EDIT: working example

<html>
    <head>
        <meta name="viewport" content="width=320px, height=240px, initial-scale=1, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
        <style>
            body {
                background: black;
                width: 100vw;
                height: 100vh;
            }
            #iframed {
                width: 320px;
                height: 200px;
            }
            #scaled-game {
                text-rendering: optimizeSpeed;
                font-smooth: never;
                backface-visibility: hidden;
                will-change: transform;
                position: absolute;
                left: 50%;
                top: 50%;
                transform: translateX(-50%) translateY(-50%) scale(2);
            }
        </style>
    </head>

    <body>
        <div id="scaled-game">
            <iframe
                id="iframed"
                scrolling="no"
                frameborder="no"
                allow="autoplay"
                width="320px"
                height="200px"
                allowfullscreen
                srcdoc='
                    <html>
                        <style>
                            body {
                                background: black;
                                text-rendering: optimizeSpeed;
                                font-smooth: never;
                                backface-visibility: hidden;
                            }
                            #game {
                                position: absolute;
                                will-change: background-position;
                                min-width: 320px;
                                width: 320px;
                                max-width: 320px;
                                min-height: 200px;
                                height: 200px;
                                max-height: 200px;
                                border: none;
                                filter: drop-shadow(0px 0px 4px green) drop-shadow(0px 0px 6px darkgreen);
                            }
                            #gui {
                                position: absolute;
                            }
                            #txt {
                                top: 0;
                                transform: translate(0%, 50%);
                                font-size: 25px;
                                text-align: center;
                                color: white;
                                text-shadow: 0px 4px 3px rgba(0,0,0,0.4), 0px 8px 13px rgba(0,0,0,0.1), 0px 18px 23px rgba(0,0,0,0.1);
                            }
                            #game:before {
                              position: absolute;
                              top: 0;
                              left: 0;
                              width: 100%;
                              height: 100%;
                              content: "";
                              transform: translateZ(0);
                              transform: translateZ(0);
                              transform-origin: 50% 50% 0;
                              animation-name: sideupscroll;
                              animation-duration: 80s;
                              animation-timing-function: linear;
                              animation-iteration-count: infinite;
                              background: url("http://i.imgur.com/wNna7D3.png") repeat fixed 0 0 indigo;
                              animation-fill-mode: both;
                              border: 2px solid white;
                              border-radius: 7px;
                            }
                            @keyframes sideupscroll {
                              0% {
                                background-position: 0 0;
                              }
                              50% {
                                background-position: -50% -100%;
                              }
                              100% {
                                background-position: -100% -200%;
                              }
                            }
                        </style>
                        <body>
                            <div id="game">
                            </div>
                            <div id="gui">
                                <p id="txt">TEXT & SHADOWS KEEP BEING SHARP</p>
                            </div>
                        </body>
                    </html>
                '>
            </iframe>
        </div>
    </body>
</html>


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source