Part 4: Layout and orientation (HTML)

[ 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 ]

The UI design for your Windows Store app is about organizing and presenting content to your users, and providing commands that enable your users to act on the content. UI design includes the organization of pages in the app, the navigation between pages, and the layout of content and commands on each page.

In this tutorial, we go over the basics of creating a user interface in HTML and Cascading Style Sheets (CSS). To learn these basics, you create a simple photo viewer that lets users pick an image from their Pictures Library and then shows the image and some info about the image file. For this tutorial, we start from scratch with a new app.

Tip  

If you want to skip the tutorial and go straight to the code, see Getting started with JavaScript: Complete code for the tutorial series.

 

Before you start...

Step 1: Create a new Navigation App in Visual Studio

Let's create a new app named PhotoAppSample that uses the Navigation App template. Here's how:

  1. Launch Microsoft Visual Studio Express 2013 for Windows.

  2. From the File menu, select New Project.

    The New Project dialog appears.

  3. In the left pane, expand Installed, then expand Templates, then expand JavaScript and select the Windows Store template type. (If you’re using Visual Studio 2013 with Update 2 or later, expand JavaScript > Store Apps and select the Windows Apps template type.) The dialog's center pane displays a list of project templates for JavaScript.

  4. In the center pane, select the Navigation App template.

  5. In the Name text box, type "PhotoAppSample".

  6. Clear the Create directory for solution check box.

  7. Click OK to create the project.

    Visual Studio creates your project and displays it in the Solution Explorer.

  8. Run the app.

Step 2: Add controls and content

  1. In Solution Explorer, double-click home.html to open it.

  2. Switch to the light style sheet. Replace this reference to the dark style sheet:

        <!-- WinJS references -->
        <link href="//Microsoft.WinJS.2.0/css/ui-dark.css" rel="stylesheet" />
    

    With this one:

        <!-- WinJS references -->
        <link href="//Microsoft.WinJS.2.0/css/ui-light.css" rel="stylesheet" />
    
  3. Change the page title to "Photo app sample".

    <body>
        <!-- The content that will be loaded and displayed. -->
        <div class="fragment homepage">
            <header aria-label="Header content" role="banner">
                <button data-win-control="WinJS.UI.BackButton"></button>
                <h1 class="titlearea win-type-ellipsis">
                    <span class="pagetitle">Photo app sample</span>
                </h1>
            </header>
            <section aria-label="Main content" role="main">
                <p>Content goes here.</p>
            </section>
        </div>
    </body>
    
  4. Replace the content of the main section with elements for selecting and displaying an image and info about the image. Create these elements:

    • A div element for containing everything.
    • A button for selecting a photo.
    • A div element for displaying the name of the image.
    • A div element for containing the image and its info (we'll use this container to help with formatting later).
    • An img element for displaying the image.
    • Another div element for containing the image info (again, we'll use this container to help with formatting later).
    • Three labels for identifying the image info
    • Three div elements for displaying the image info.

    Here's the updated markup:

    <body>
        <!-- The content that will be loaded and displayed. -->
        <div class="fragment homepage">
            <header aria-label="Header content" role="banner">
                <button data-win-control="WinJS.UI.BackButton"></button>
                <h1 class="titlearea win-type-ellipsis">
                    <span class="pagetitle">Photo app sample</span>
                </h1>
            </header>
            <section aria-label="Main content" role="main">
                <div id="contentGrid">
                    <button id="getPhotoButton">Get photo</button>
                    <div id="imageName" class="pageSubheader">Image name</div>
    
                    <div id="imageGrid">
                        <img id="displayImage" src="#"  />
                        <div id="imageInfoContainer">
                            <label for="fileName">File name:</label>
                            <div id="fileName">File name</div>
                            <label for="path">Path:</label>
                            <div id="path">Path</div>
                            <label for="dateCreated">Date created:</label>
                            <div id="dateCreated">Date created</div>
                        </div>
                    </div>
                </div>
            </section>
        </div>
    </body>
    
  5. Run the app.

    It doesn't look like much yet. In the next steps, you arrange the elements in a grid layout.

Step 3: Define the main content grid

In the past, it was common to use HTML tables for page layout. CSS now provides the Grid layout and the Flexible box ("Flexbox") layout. These layout systems provide more features and are more flexible than traditional HTML tables.

In this tutorial, we use the grid layout. The grid layout lets you align elements in columns and rows.

To create a grid layout, you create a container element (such as a div) and set its display property to "-ms-grid"

<div style="border: 1px solid gray; width: 800px; display: -ms-grid">
    <p style="margin: 2px; border: 1px solid gray;">Child element 1</p>
    <p style="margin: 2px; border: 1px solid gray;">Child element 2</p>
    <p style="margin: 2px; border: 1px solid gray;">Child element 3</p>
    <p style="margin: 2px; border: 1px solid gray;">Child element 4</p>
    <p style="margin: 2px; border: 1px solid gray;">Child element 5</p>
</div>

Next, you specify the tracks (columns and rows) in the grid layout. You use the -ms-grid-columns and -ms-grid-rows properties to specify the number and size of columns and rows. You can size columns and rows (collectively referred to as tracks) using any of the following:

  • Standard length units, such as pixels
  • A percentage of the object's width (for columns) or height (for rows)
  • The auto keyword, indicating that the width of the column or height of the row is sized based on the items inside it
  • The min-content keyword, indicating that the minimum width or height of any child elements is used as the width or height
  • The max-content keyword, indicating that the maximum width or height of any child elements is used as the width or height
  • The minmax(a, b**)** keyword, indicating that the width or height is between a and b, as available space allows
  • Fraction units (fr), indicating that the available space should be divided among the columns or rows according to their fraction values.

This example uses pixels, the auto keyword, and fractional units to set the size of columns and rows in the grid.

<div style="border: 1px solid gray; width: 800px; display: -ms-grid
            -ms-grid-columns: auto 100px 1fr 2fr; 
            -ms-grid-rows: 50px auto">
    <p style="margin: 2px; border: 1px solid gray;">Child element 1</p>
    <p style="margin: 2px; border: 1px solid gray;">Child element 2</p>
    <p style="margin: 2px; border: 1px solid gray;">Child element 3</p>
    <p style="margin: 2px; border: 1px solid gray;">Child element 4</p>
    <p style="margin: 2px; border: 1px solid gray;">Child element 5</p>
</div>

This grid has four columns, and each column appears as described here:

  • Column 1 (auto keyword): The column is fitted to the content in the column.
  • Column 2 ("100px"): The column is 100 pixels wide.
  • Column 3 ("1fr"): The column takes up one fraction unit of the remaining space.
  • Column 4 ("2fr"): the column takes up two fraction units of the remaining space.

Because there are three total fraction units in this grid, Column 3 is allotted 1 fraction unit divided by 3 fraction units—or 1/3—of the remaining space. Column 4 is allotted 2/3 of the remaining space.

Similarly, this grid has two rows, and each row appears as described here:

  • Row 1 ("50px"): The row is 50 pixels tall.
  • Row 2 (auto keyword): The row is fitted to the content in the row.

To position child items in the grid, you use the -ms-grid-column and -ms-grid-row properties to specify the column and row of each item.

<div style="border: 1px solid gray; width: 800px; display: -ms-grid; 
            -ms-grid-columns: auto 100px 1fr 2fr; 
            -ms-grid-rows: 50px auto">
    <p style="margin: 2px; border: 1px solid gray; 
                -ms-grid-column: 1; 
                -ms-grid-row: 1">Child element 1</p>
    <p style="margin: 2px; border: 1px solid gray; 
                -ms-grid-column: 2; 
                -ms-grid-row: 1">Child element 2</p>
    <p style="margin: 2px; border: 1px solid gray; 
                -ms-grid-column: 3; 
                -ms-grid-row: 1">Child element 3</p>
    <p style="margin: 2px; border: 1px solid gray; 
                -ms-grid-column: 4; 
                -ms-grid-row: 1">Child element 4</p>
    <p style="margin: 2px; border: 1px solid gray; 
                -ms-grid-column: 1; 
                -ms-grid-row: 2">Child element 5</p>
</div>

Now that you understand the basics of using a grid layout, let's update our app to use a grid layout.

To define the main content grid

  1. In the Solution Explorer, double-click home.css to open it. The first style in the file, .homepage section[role=main], defines a margin for the main section. Let's remove the margin setting and leave the style blank for now.

    .homepage section[role=main] {
    
    }
    
  2. Let's set up the primary grid container. Your home.html contains a div element named contentGrid. This will be our top-level grid.

    Open your home.css file and create a style for contentGrid just after the style for .homepage section[role=main]. Set its display property to -ms-grid and give it a single column and three rows. Set the first row to 50 pixels, the second row to 70 pixels, and the third row to auto. Give it top margin of 20 pixels and a left and right margin of 120 pixels.

    #contentGrid {
        display: -ms-grid; 
        -ms-grid-rows: 50px 70px auto; 
        margin: 20px 120px 0px 120px;
    }
    
  3. Our content grid contains three elements: getPhotoButton, imageName, and imageContainer. Define styles for them that put them in the first, second, and third row of the content grid.

    While we're updating the getPhotoButton style, let's give it a height of 20 pixels.

    #getPhotoButton {
        -ms-grid-row: 1;
        width: 120px;
        height: 20px;
    }
    
    #imageName {
        -ms-grid-row: 2;
    }
    
    #imageGrid {
        -ms-grid-row: 3; 
    }
    
  4. Define a style for the pageSubheader class.

    .pageSubheader {
        font-family: 'Segoe UI Light';
        font-size: 20px;
        vertical-align: bottom;
        margin: 0px 0px 40px 0px;
    }
    
  5. Run the app.

We defined a main content grid. Our content is now divided into three rows. If you could see the outlines of the rows, they'd look something like this.

Step 4: Define the layout for the rest of the page

Now that we've created the main content grid, let's finish laying out the rest of the app.

To define the layout for the rest of the page

  1. Define a grid for the image and accompanying image info. Open home.css and update the style that you created for imageGrid in the last step. Make imageGrid a two-column grid. Set each column width to auto.

    #imageGrid {
        -ms-grid-row: 3; 
        display: -ms-grid;
        -ms-grid-columns: auto auto;
    }
    
  2. After the style for imageGrid, create a style for the displayImage element. Make it appear in the first column of the imageGrid, set its width to 375 pixels and its max-height to 375 pixels, give it a black border, and set its background color to "gray".

    #displayImage {
        -ms-grid-column: 1;
        width: 375px;
        max-height: 375px; 
        border: 1px solid black;
        background-color: gray; 
    
    }
    
  3. Create a style for the imageInfoContainer element. Make it appear in the second column of the imageGrid and give it a left margin of 20 pixels.

    #imageInfoContainer {
        -ms-grid-column: 2;
        margin-left: 20px; 
    }
    
  4. Create a style for the div elements inside the imageInfoContainer element. Give them a 20-pixel left margin, a 40-pixel bottom margin, set their width to 400 pixels, and set their word-wrap to "break-word".

    #imageInfoContainer > div {
        margin-left: 20px;
        margin-bottom: 40px;
        width: 400px; 
        word-wrap: break-word;
    }
    
  5. Run the app.

Step 5: Adapt the page layout to different orientations and views

So far, you've designed the app to be viewed full screen in the landscape orientation. But a Windows Store app must adapt to different orientations and layouts. Here, we see how you can make your app look good in any resolution or orientation.

The easiest way to see what your app looks like in different views is to use Blend for Microsoft Visual Studio 2013. Blend provides a visual designer that makes it easy to preview and modify your UI. Let's give it a try.

  1. Launch Blend.
  2. On the File menu, select Open Project/Solution.
  3. In the Open Project dialog box, go to the location that contains your PhotoAppSample app and select the solution file, and then click Open.

As you can see, the Blend environment looks quite a bit different from Microsoft Visual Studio.

Let's take a high-level look at the Blend workspace. We'll start at the center of the workspace.

The majority of the center panel displays the artboard. The artboard is where you perform most visual layout tasks. Notice that the application area is framed by a virtual tablet device.

Below the artboard is your HTML and CSS code. The current view (called the Split view) displays both code and the artboard. You can switch between the different views (Design, Code, and Split ) by clicking the buttons in the upper-right corner of the artboard panel:

Now let's take a look at some of the panels that surround the center workspace.

Panel Image Description
Projects

The upper-left corner of the workspace contains the Projects panel.

The Projects panel is similar to the Solution Explorer in Visual Studio. You can use it to open files and add new items.

Live DOM

Below the Projects panel is the Live DOM panel.

The Live DOM panel shows the structure of the app that you’re designing and lets you select elements that you want to style. More important, the Live DOM view automatically and dynamically updates as the state of the app changes, including changes to elements declared in the HTML markup and elements that are dynamically generated.

CSS Properties

The CSS Properties panel is where you can view and modify the CSS properties of an HTML element that is selected on the artboard or in the Live DOM panel.

Style Rules

The Style Rules panel lists all of the style sheets attached to the current document and all of the styles defined in them.

Device

The Device panel is where you select displays, views, and other display options for your app.

 

Let's use the Device panel to see what the app looks like in portrait orientation.

In the Device panel, click the portrait () button. The designer changes to simulate the portrait view.

This is what the app looks like when the user rotates it to portrait orientation. Let's make some adjustments so the app can take advantage of the additional vertical space available in portrait mode.

To adjust the portrait view

  1. In the Device panel, click the portrait () view button to show the portrait view.

  2. In the Style Rules panel, right-click on the home.css entry and select **Add At-Rule... > Add @media** rule from the context menu.

  3. The Add @media Rule dialog appears. Select screen and (orientation: portrait) and click OK.

  4. Expand the home.css entry if it isn't already expanded. Right click the @media screen and (orientation: portrait) entry that you just created and select Add Style Rule.

    Blend creates a style called .newStyle.

  5. Select .newStyle and rename it ".homepage section[role=main]". Select this style.

  6. In the CSS Properties panel, expand the Layout section. Set the left margin to 0 pixels.

  7. In the Style Rules panel, next to the @media screen and (orientation: portrait) entry, click the Add New Style button ().

  8. Set the new style name to "#imageGrid" and select it.

  9. In the CSS Properties panel, expand the Grid section. Set -ms-grid-columns to "auto" and -ms-grid-rows to "auto auto".

  10. In the Style Rules panel, next to the @media screen and (orientation: portrait) entry, click the Add New Style button () again. Name this style "#imageInfoContainer" and select it.

  11. In the CSS Properties panel, expand the Grid section. Set -ms-grid-column to "1" and -ms-grid-row to "2".

  12. Expand the Layout section. Set the top margin to "20px" and the left margin to "0px".

    Here's what the updated CSS looks like.

    @media screen and (orientation: portrait) {
        .homepage section[role=main] {
            margin-left: 0px;
        }
    
        #imageGrid {
            -ms-grid-columns: auto;
            -ms-grid-rows: auto auto;
        }
    
        #imageInfoContainer {
            -ms-grid-column: 1;
            -ms-grid-row: 2;
            margin-top: 20px;
            margin-left: 0px;       
        }
    }
    
  13. Press Ctrl + S to save your work.

  14. Run the app. It now looks like this in the portrait view.

Summary

Congratulations, you're done with the fourth tutorial! You learned how to use a grid layout and create styles for different orientations. You also learned how to use Blend to design your UI.

Download the sample

Did you get stuck, or do you want to check your work? If so, download the Getting started with JavaScript sample.

Next steps

In the next part of this tutorial series, you learn how to create a more complex app. Go to Part 5: File access and pickers.

Getting started with JavaScript: Complete code for the tutorial series

Programming Windows 8 Apps with HTML, CSS, and JavaScript (ebook)