Part 4: Layout and views (Windows Store apps using JavaScript and HTML)

12 out of 26 rated this helpful - Rate this topic

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 2012 for Windows 8.
  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. 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.

    The New Project window

  7. Click OK to create the project.

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

    The Soution Explorer for the PhotoAppSample project

  8. Run the app.

    The PhotoAppSample app

Step 3: 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.1.0/css/ui-dark.css" rel="stylesheet" />
    
    
    

    With this one:

    
    
        <!-- WinJS references -->
        <link href="//Microsoft.WinJS.1.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 class="win-backbutton" aria-label="Back" disabled type="button"></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 class="win-backbutton" aria-label="Back" disabled type="button"></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.

    The PhotoAppSample 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>

JJ841108.js_tut_4_grid(en-us,WIN.10).png

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

JJ841108.wedge(en-us,WIN.10).gifTo 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.

    PhotoAppSample after addition of the main content grid.

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.

PhotoAppSample with content grid rows outlined.

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.

JJ841108.wedge(en-us,WIN.10).gifTo 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.

    PhotoAppSample, with additional layout

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. Specifically, it must support both landscape and portrait orientations. In the landscape orientation, it must support full screen, filled, and snapped 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 2012 for Windows 8. 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.

PhotoAppSample in Blend for Visual Studio

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

The center workspace in Blend

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:

JJ841108.js_tut_4_blend_artboardswitcher(en-us,WIN.10).png

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

PanelImageDescription
Projects

The Projects panel in Blend

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

The Live DOM panel in Blend

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 in Blend

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 in Blend

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

DeviceThe Device panel in Blend

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

 

Let's use the Device panel to try out the different views to see how the app looks.

JJ841108.wedge(en-us,WIN.10).gifTo use different views in Blend

  1. In the Device panel, click the filled (Filled view button) view button. The artboard changes to show the filled view. This is what the app looks like when the user snaps another app next to it. This view looks okay, so you can leave it as is.

    PhotoAppSample in the filled view

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

    This is what the app looks when the user snaps it next to another app. This view is too narrow to show the whole app, so you need to make some adjustments for this to work.

    PhotoAppSample in the snapped view

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

    This is what the app looks like when the user rotates it to portrait orientation. This view is also too narrow. You need to make some adjustments similar to those you make for the snapped view.

    PhotoAppSample in the portrait view

First, let's adjust the snapped view.

JJ841108.wedge(en-us,WIN.10).gifTo adjust the snapped view

  1. In the Device panel, click the snapped (Snapped view button) button to show the snapped view.
  2. In the Projects panel, double-click home.css to open it.
  3. Scroll to the end of the file and take a look at one of the last sections:
    
    @media screen and (-ms-view-state: snapped) {
        .homepage section[role=main] {
            margin-left: 20px;
        }
    }
    
    
    

    This section uses a media query to apply styles when the app is in the snapped state. This particular media query and style was created for us by the Visual Studio template. Let's update this style by removing the margin setting from the .homepage section[role=main] style (just like we did for the non-snapped version).

    
    @media screen and (-ms-view-state: snapped) {
        .homepage section[role=main] {
        }
    }
    
    
    
  4. One of the snapped-view layout issues with our app is that the left margin is too big. Let's create a snapped view style for the contentGrid that changes the margin from 120 pixels to 20 pixels.
    
    @media screen and (-ms-view-state: snapped) {
        .homepage section[role=main] {
        }
    
        #contentGrid {
            margin-left: 20px;
        }
    }
    
    
    
  5. In the Projects panel, double-click default.html to open it and display the artboard. The content is now closer to the left.

    The app in the snapped view

  6. Let's verify that our update applies only to the snapped view. In the Device panel, click the landscape (Landscape view button) view button to show the landscape view. The left margin goes back to 120 pixels.

    The app in landscape view

  7. Let's go back to the snapped view. In the Device panel, click the snapped (Snapped view button) view button to show the snapped view.
  8. In the Projects panel, double-click home.css to open it again. Go back to the snapped media query section.
  9. Change the style of the imageGrid so that it has one column (instead of two) and two rows (instead of one).

    
    @media screen and (-ms-view-state: snapped) {
        .homepage section[role=main] {
        }
    
        #contentGrid {
            margin-left: 20px;
        }
    
        #imageGrid {
            -ms-grid-columns: auto;
            -ms-grid-rows: auto auto;
        }
    }
    
    
    
  10. Change the style of the imageInfo container so that it's in the first column and the second row, set its top margin to 20 pixels, and set its left margin to 0 pixels.
    
    @media screen and (-ms-view-state: snapped) {
        .homepage section[role=main] {
        }
    
        #contentGrid {
            margin-left: 20px;
        }
    
        #imageGrid {
            -ms-grid-columns: auto;
            -ms-grid-rows: auto auto;
        }
    
        #imageInfoContainer {
            -ms-grid-row: 2;
            -ms-grid-column: 1;
            margin-top: 20px;
            margin-left: 0px;
        }
    }
    
    
    
  11. Change the style of the displayImage so that its width is 225 pixels and its max-height is 225 pixels.
    
    @media screen and (-ms-view-state: snapped) {
        .homepage section[role=main] {
        }
    
        #contentGrid {
            margin-left: 20px;
        }
    
        #imageGrid {
            -ms-grid-columns: auto;
            -ms-grid-rows: auto auto;
        }
    
        #imageInfoContainer {
            -ms-grid-row: 2;
            -ms-grid-column: 1;
            margin-top: 20px;
            margin-left: 0px;
        }
    
        #displayImage {
            width: 225px;
            max-height: 225px;
        }
    }
    
    
    
  12. Change the style of the div elements inside the imageInfo element so that they are 250 pixels wide.
    
    @media screen and (-ms-view-state: snapped) {
        .homepage section[role=main] {
        }
    
        #contentGrid {
            margin-left: 20px;
        }
    
        #imageGrid {
            -ms-grid-columns: auto;
            -ms-grid-rows: auto auto;
        }
    
        #imageInfoContainer {
            -ms-grid-row: 2;
            -ms-grid-column: 1;
            margin-top: 20px;
            margin-left: 0px;
        }
    
        #displayImage {
            width: 225px;
            max-height: 225px;
        }
    
        #imageInfoContainer > div {
            width: 250px; 
        }
    
    }
    
    
    
  13. Press Ctrl + S to save your work.
  14. In the Projects panel, double-click default.html to open it and display the artboard. In the Device panel, click the snapped (Snapped view button) view button to show the snapped view.

    The app now looks like this in the snapped view.

    The app in snapped view

Now, let's fix the portrait view. This time, we'll use the Blend UI to make the changes, rather than editing CSS code directly.

JJ841108.wedge(en-us,WIN.10).gifTo adjust the portrait view

  1. In the Device panel, click the portrait (Portrait view button) view button to show the portrait view.
  2. n the Style Rules panel, expand the home.css entry and select the @media screen and (-ms-view-state: portrait) entry.

    The Blend Style Rules panel

  3. Click the entry a second time and rename it @media screen and (-ms-view-state: fullscreen-portrait).
  4. Select this .homepage section[role=main] style style. This is the .homepage section[role=main] style style for the portrait view.

    The main section style for the portrait view

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

    The CSS Properties panel in Blend

  6. In the Style Rules panel, next to the @media screen and (-ms-view-state: portrait) entry, click the Add New Style button (Add New Style button in Blend).
  7. Set the new style name to "#imageGrid" and select it.
  8. In the CSS Properties panel, expand the Grid section. Set -ms-grid-columns to "auto" and -ms-grid-rows to "auto auto".

    Grid styles for the imageGrid element

  9. In the Style Rules panel, next to the @media screen and (-ms-view-state: portrait) entry, click the Add New Style button (JJ841108.js_tut_4_addnewstyleicon(en-us,WIN.10).png) again. Name this style "#imageInfoContainer" and select it.
  10. In the CSS Properties panel, expand the Grid section. Set -ms-grid-column to "1" and -ms-grid-row to "2".

    Grid styles for the imageInfoContainer element

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

    Layout styles for the imageInfoContainer element

    Here's what the updated CSS looks like.

    
    @media screen and (-ms-view-state: fullscreen-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;
        }
    }
    
    
  12. Press Ctrl + S to save your work.
  13. Run the app. It now looks like this in the portrait view.

    The app in portrait view

Summary

Congratulations, you're done with the fourth tutorial! You learned how to use a grid layout and create styles for different view states. 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.

Related topics

Getting started with JavaScript: Complete code for the tutorial series
Programming Windows 8 Apps with HTML, CSS, and JavaScript (ebook)

 

 

Build date: 3/11/2013

Did you find this helpful?
(1500 characters remaining)
© 2013 Microsoft. All rights reserved.