Automatically Scale an Element to Fill the Screen

You can use JavaScript and jQuery to scale an element so that it uses as much of the screen as possible, regardless of the device's orientation. This technique is useful for fixed-sized games to maximize play area regardless of what device is in use.

The FillScreen sample demonstrates this technique. The code for this sample is located in the following folder of the Amazon Web SDKs:

Amazon-Web-SDKs/Webapps/examples/Cookbook/FillScreen/

Download the Amazon Web SDKs from the SDK Download page (click the Web button).

Initial Markup and Style

The initial markup and style needed are as follows:

<div id="fill">
  content goes here
</div>

body {
  padding: 0;
  margin: 0;
}

#fill {
  width: 300px;
  height: 400px;
  border: 1px solid red;
}

The applied styles remove all padding and margin, and create a 300px × 400px content area with a 1px red border for visibility.

Scaling Function

The scaling function takes two parameters: a div to be scaled and a boolean called proportional that is used to determine whether the width and height of the div to be scaled should remain in proportion to one another, or if they can be scaled independently. The function performs these steps to determine how to scale and position the div:

  1. The function determines the current width and height of the div to be scaled, and the available width and height of the viewport.
  2. The available width is divided by the current width, and the available height is divided by the current height. The resulting values are scaling factors.
  3. If proportional is true, both scaling factors are set to be equal to the smaller of the two so that the width and height remain in proportion to each other without exceeding the visible portion of the screen. Otherwise, the sides will be scaled independently to take up as much space as possible.
  4. The function determines translation factors so that the scaled div can be positioned so that it remains centered on the screen.
  5. The function updates the div's CSS properties with the values of the scaling and translation factors.

Here is an example implementation of the scaling function:

function fillDiv(div, proportional) {
  var currentWidth = div.outerWidth();
  var currentHeight = div.outerHeight();

  var availableHeight = window.innerHeight;
  var availableWidth = window.innerWidth;

  var scaleX = availableWidth / currentWidth;
  var scaleY = availableHeight / currentHeight;

  if (proportional) {
    scaleX = Math.min(scaleX, scaleY);
    scaleY = scaleX;
  }

  var translationX = Math.round((availableWidth - (currentWidth * scaleX)) / 2);
  var translationY = Math.round((availableHeight - (currentHeight * scaleY)) / 2);

  div.css({
    "position": "fixed",
    "left": "0px",
    "top": "0px",
    "-webkit-transform": "translate(" + translationX + "px, "
                                      + translationY + "px) scale3d("
                                      + scaleX + ", " + scaleY + ", 1)",
    "-webkit-transform-origin": "0 0"
  });
}

Invoke the Scaling Function

The scaling function needs to be called when the app starts up and whenever the screen orientation changes. Once the window's content has been fully loaded, call the fillDiv function to scale and center the div. Additionally, bind a handler that calls fillDiv to screen orientation events so that whenever a screen orientation event is detected, fillDiv is called.

Here is a sample function, initialize(), that calls fillDiv() and binds a handler to screen orientation events. The initialize() function is bound to the window's load event:

function initialize() {
  var div = $("#fill");
  fillDiv(div, true);

  if ("onorientationchange" in window) {
    console.log("Using orientationchange");
    // There seems to be a bug in some Android variants such that the
    // metrics like innerHeight and outerHeight (used in fillDiv above)
    // are not updated when the orientationEvent is triggered. The
    // half-second delay gives the browser a chance to update the
    // metrics before rescaling the div.
    $(window).bind("orientationchange", function() { setTimeout(function() { fillDiv(div, true); }, 500) });
  } else if ("ondeviceorientation" in window) {
    console.log("Using deviceorientation");
    // Unlike the event above this not limited to a horzontal/vertical
    // flip and will trigger for any device orientation movement
    $(window).bind("deviceorientation", function() { setTimeout(function() { fillDiv(div, true); }, 500) });
  else {
    console.log("No orientation supported, fallback to resize");
    $(window).bind("resize", function() { fillDiv(div, true); });
  }
}

$(window).load(initialize);