JSFiddle - React, Tailwind, and code Playground

HTML

<div class="game">
<div id="contain">
</div>
</div>
<p>Drawing a checkerboard that is 48 x 48 with two gutters and background. Result image caching replaces a total of 2306 draws per frame.</p>

CSS

.game {
    background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAI0lEQVQIW2PkdmD+z2vAwfD5wg8GGM0oUcD9H1kAJMFImUoAlhAlEcHdcCMAAAAASUVORK5CYII=);
    padding: 10px;
}
#contain {
    width: 0px;
    height: 0px;
    margin: 0 auto;
    position: relative;    

    background: #FFF;
    border: 1px solid black;
}

JavaScript

(function(){
    // Variables
    var width = 0;
    var height = 0;
    var tileWidth = 5;
    var tileHeight = 5;
    var widthInTiles = 48;
    var heightInTiles = 48;    
    var paddingTop = 10;
    var paddingLeft = 10;
    var paddingRight = 10;
    var paddingBottom = 10;    
    var gutterLeft = 170;
    var gutterBottom = 50;
    
    // The container div
    var contain = document.getElementById('contain');

    // Create our canvases in script, why not?
    var surface1 = document.createElement('canvas');
        surface1.id = 'surface1'
        surface1.innerHTML = 'Sorry, no canvas for you';
        surface1.style.position='absolute';
        surface1.style.top = paddingTop + 'px';
        surface1.style.left = paddingLeft + 'px';     
    
    width = tileWidth * widthInTiles + gutterLeft;
    height = tileHeight * heightInTiles + gutterBottom;

    surface1.width = width;
    surface1.height = height;
    
    // Add our canvas    
    contain.appendChild(surface1);
    
    // Set the size of the contain element
    // Take into account the padding we want
    contain.style.width = (width + paddingLeft + paddingRight) + 'px';
    contain.style.height = (height + paddingTop + paddingBottom) + 'px';

    // Draw the surface
    if (surface1.getContext) {
        var context = surface1.getContext("2d");
        if (context != null) {
            for (var y = 0; y < heightInTiles; y++) {
                for (var x = 0; x < widthInTiles; x++) {

                    // Yay checkerboard pattern
                    if ((y % 2 + x % 2) == 1) {
                        context.fillStyle = "rgba(0,0,0,.5)";
                    } else {
                        context.fillStyle = "rgba(255,0,0,.2)";                    
                    }
                    // Draw the tile
                    context.fillRect(gutterLeft + (x * tileWidth), (y * tileHeight), tileWidth + 200, tileHeight);
                }
            }
            
            // Draw some...