Quickstart: Designing apps for different window sizes

[This article is for Windows 8.x and Windows Phone 8.x developers writing Windows Runtime apps. If you’re developing for Windows 10, see the latest documentation]

When you design an app to look good and function well at any window size, you must choose if you want to create additional layouts to complement the default full-screen horizontal layout. You can design your app to support a minimum width of 320 pixels instead of the default minimum of 500 pixels, and to switch to a vertical layout when the app is taller than it is wide. These are optional design choices.

See this feature in action as part of our App features, start to finish series: Windows Store app UI, start to finish

Objective: After reading this article, you will understand how to change the minimum width of an app from 500 pixels to 320 pixels, and how to change your design so that the app looks good and functions well at narrow widths. You will also understand how to design a horizontally panning app that changes to a vertical layout any time the app height is greater than the width.

Prerequisites

Create your first Windows Store app using JavaScript

UX guidelines for layout and scaling

The sample: Layout for windows that are taller than wide

This article demonstrates the additional design options for tall and narrow layouts by describing how they are implemented in the Layout for windows that are taller than wide sample. This sample is based on the Grid App template in Microsoft Visual Studio.

The Grid App template has four pages:

  • default (default.html), which simply loads the groupedItems page after the app starts.
  • groupedItems (pages\groupItems\groupedItems.html), which enables the user to view groups and items, and either select a group label to navigate to the group details page (groupDetail), or select an item to navigate to the full-page item view (itemDetail).
  • groupDetail (pages\groupDetail\groupDetail.html), which enables the user to view group details and items, and select an item to navigate to the full-page item view (itemDetail).
  • itemDetail (pages\itemDetail\itemDetail.html), which represents the full-page view of an item.

In this article, you'll use the default layout for each page. We discuss only changes that are needed to the JavaScript code behind the groupDetail and groupedItems pages.

The key coding technique here is to check for changes to a page's offsetWidth and offsetHeight properties. If certain width and height values are reached as a result of the user changing the page's width or device orientation, the page changes the layout and behavior of its controls.

To try this out, in Visual Studio, create a new instance of the JavaScript Windows Store Grid App project, and then follow the rest of these instructions.

Define the minimum width

By default, the minimum width of a Windows Store app is 500 pixels. The height of the app always fills the screen. The minimum screen height for an app is 768 pixels.

If your app works well at narrow widths, or if multitasking is an important scenario for your app and you want users to keep it on the same screen as other apps, you can change the minimum width to 320 pixels instead of 500. That way, users can resize your app fluidly to any size, from full screen down to 320 pixels wide.

You change the minimum width of the app in the package.appxmanifest manifest file. To do this, in Visual Studio, complete these steps.

  1. Open the package.appxmanifest manifest file. The manifest opens automatically in the Manifest Designer.

  2. Open the Application tab and find the Minimum width field.

  3. Use the drop-down list to change the minimum width to 320 px.

  4. If you open the package.appxmanifest manifest file in a text editor, you should see the ApplicationView element as a child of the VisualElements element. For example, the new minimum width in the manifest file looks like this.

    <ApplicationView MinWidth="width320" /> 
    

Now that your app is capable of being resized down to 320 pixels, you need to modify your app so that it is usable at narrow widths. Specifically, you'll switch your app so that it pans vertically instead of horizontally.

Define behavior for the groups and items view

  1. In the pages\groupedItems\groupedItems.js file, add code to the ui.Pages.define function's ready method. This method is called after all page initialization and rendering is complete. In this method, call the _initializeLayout function, which you'll define later. (For reference, the code that you need to add is marked by *** START *** and *** END *** comments.)

    ui.Pages.define("/pages/groupedItems/groupedItems.html", {
        // ...
        ready: function (element, options) {
            var listView = element.querySelector(".groupeditemslist").winControl;
            listView.element.focus();
            // *** START ***
            this._initializeLayout(listView);
            // *** END ***
        },
        // ...
    
  2. In the groupedItems.js file, add code to the ui.Pages.define function's updateLayout method. This method is called whenever the user switches the app between layout states such as narrow, portrait, and landscape. In this method, make a reference to the page's ListView control, temporarily disable page animations, and then call the _initializeLayout function, which you'll define later.

    ui.Pages.define("/pages/groupedItems/groupedItems.html", {
        // ...
        updateLayout: function (element) {
            /// <param name="element" domElement="true" />
    
            // TODO: Respond to changes in layout.
            // *** START ***
            var listView = element.querySelector(".groupeditemslist").winControl;
    
            // Don't show page entrance animations when the app switches layouts.
            var handler = function (e) {
                listView.removeEventListener("contentanimating", handler, false);
                e.preventDefault;
            }
            listView.addEventListener("contentanimating", handler, false);
    
            this._initializeLayout(listView);
            // *** END ***
        },
        // ...
    
  3. In the groupedItems.js file, add code to the ui.Pages.define function to define the _initializeLayout function. This function determines whether the page is in a narrow, portrait, or landscape layout, and adjusts the page's ListView control accordingly. Both the ready and updateLayout methods call this function. Here's what this function does.

    • If the page's width is greater than 320 pixels but less than 500 pixels, the page's ListView control shows the data as a vertically-scrolling list of groups only. (500 pixels is an example width. You can decide at what width you want the layout to change. In this sample, we chose 500 pixels as the point at which the app switches its layout. At any width below 500 pixels, the app uses a narrow layout.)
    • If the page's width is less than its height, the ListView control shows the data as a vertically-scrolling list of groups that contain items.
    • Otherwise, the ListView control shows the data as a horizontally-scrolling grid of groups that contain items.
    ui.Pages.define("/pages/groupedItems/groupedItems.html", {
        // ...
        // *** START ***
        _initializeLayout: function (listView) {
            // Narrow layout.
            if (document.documentElement.offsetWidth < 500) {
                // Show data as a vertically-scrolling list of groups only.
                listView.itemDataSource = Data.groups.dataSource;
                listView.groupDataSource = null;
                listView.layout = new ui.ListLayout();                
            }
            // Portait layout.
            else if (document.documentElement.offsetWidth < document.documentElement.offsetHeight) {
                // Show data as as a vertically-scrolling list of groups that contain items.
                listView.itemDataSource = Data.items.dataSource;
                listView.groupDataSource = Data.groups.dataSource;
                listView.layout = new ui.ListLayout();                                
            }
            // Landscape layout.
            else {
                // Show data as a horizontally-scrolling grid of groups contain items.
                listView.itemDataSource = Data.items.dataSource;
                listView.groupDataSource = Data.groups.dataSource;
                listView.layout = new ui.GridLayout();
            }
        },
        // *** END ***
        // ...
    

Define behavior for the group details and items details view

  1. In the pages\groupDetail\groupDetail.js file, add code to the ui.Pages.define function's updateLayout method. This method is called whenever the user switches the app between portrait and landscape layouts. In this method, make a reference to the page's ListView control, temporarily disable page animations, and then call the _initializeLayout function, which you'll define later. Also, scroll the ListView control so that the correct item is the first item visible.

    ui.Pages.define("/pages/groupDetail/groupDetail.html", {
        // ...
        updateLayout: function (element) {
            /// <param name="element" domElement="true" />
    
            // TODO: Respond to changes in layout.
            // *** START ***
            var listView = element.querySelector(".itemslist").winControl;
    
            // Don't show page entrance animations when the app switches layouts.
            var handler = function (e) {
                listView.removeEventListener("contentanimating", handler, false);
                e.preventDefault();
            }
            listView.addEventListener("contentanimating", handler, false);
    
            var firstVisible = listView.indexOfFirstVisible;
    
            this._initializeLayout(listView);
    
            if (firstVisible >= 0 && listView.itemDataSource.list.length > 0) {
                listView.indexOfFirstVisible = firstVisible;
            }
            // *** END ***
        },
        // ...
    
  2. In the groupDetail.js file, add code to the ui.Pages.define function to define the _initializeLayout function. This function determines whether the page is in a portrait or landscape layout, and adjusts the page's control accordingly. The updateLayout method calls this function. Here's what this function does.

    • If the page's width is greater than 320 pixels but less than 500 pixels, the page's ListView control shows the data as a vertically-scrolling list of groups only. (500 pixels is an example width. You can decide at what width you want the layout to change. In this sample, we chose 500 pixels as the point at which the app switches its layout. At any width below 500 pixels, the app uses a narrow layout.)
    • If the page's width is less than its height, the ListView control shows the data as a vertically-scrolling list without showing a group header.
    • Otherwise, the ListView control shows the data as a horizontally-scrolling grid with the group header showing to the left.
    ui.Pages.define("/pages/groupDetail/groupDetail.html", {
        // ...
        // *** START ***
        _initializeLayout: function (listView) {
            // Portrait layout.
            if (document.documentElement.offsetWidth < document.documentElement.offsetHeight) {
                listView.layout = new ui.ListLayout();
                var header = document.getElementsByTagName("header");
                header.item(0).style.display = "none";
            }
            // Landscape layout.
            else {
                listView.layout = new ui.GridLayout({ groupHeaderPosition: "left" });
                var header = document.getElementsByTagName("header");
                header.item(0).style.display = "inherit";
            }
        },
        // *** END ***
        // ...
    

Switch layouts

Now you can see what happens to the app's layout when you switch window sizes.

  1. In Visual Studio, start the app in the simulator. (To learn how, see Run Windows Store apps in the simulator.)
  2. Click Basic touch mode.
  3. Drag the top of the page to the side, and move the divider so that the page is 500 pixels wide. The data shows as a vertically-scrolling list of groups that contain items.
  4. Move the divider so that the page is 320 pixels wide. The data shows as a vertically-scrolling list of groups only.
  5. Click Rotate clockwise. The data shows as a vertically-scrolling list of groups that contain items.
  6. Experiment with tapping group titles, item titles, and the back button, as well as changing page widths and device orientations.

Summary

You should now understand how you can design your app so that it looks good and functions well at narrow widths and in layouts that are taller than wide.

Quickstart: Defining app layouts