October 2013

Volume 28 Number 10

Modern Apps - Build a Responsive and Modern UI with CSS for WinJS Apps

By Rachel Appel | October 2013

Rachel AppelWorking with CSS leaves many developers frustrated because it’s full of nuances. Even minor changes to one selector or HTML element often propagate and affect another. Trying to keep CSS clean and effective can be quite difficult, considering its numerable quirks—especially when targeting multiple browsers. Luckily, if you’re developing Windows Library for JavaScript (WinJS) apps, the CSS built in to the Visual Studio project templates is flexible yet consistent and maintainable. The Visual Studio project templates contain code that’s the foundation of a responsive and modern UI design.

Built-in CSS for Windows Store Apps

All project templates for Windows Store apps built with JavaScript contain two basic style sheets or themes—dark (default) and light—in files named ui-dark.css and ui-light.css, respectively. These files are part of a core set of project files in the CSS folder under the Visual Studio project references node. There are nearly 4,000 lines of CSS in the core CSS files because they construct a UI that follows all the principles of Windows UI design, including responding to Windows snap view and media type changes. You shouldn’t try to modify the built-in style sheets (they’re read-only), but instead overwrite the built-in styles in your own CSS files.

To use the built-in Windows Store app CSS, add the following reference to the <head> section of any page (note that “2.0” in the link is for Windows 8.1, while “1.0” would be used for Windows 8):

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

Two forward slashes at the start of the path indicate a reference to a WinJS core library (also referred to as “shared libraries,” as opposed to local project files in your app package). Paths in Windows Store apps built with JavaScript that begin with a single forward slash denote the path starts at the project’s root folder, and single forward slashes refer to local project files. 

Windows Store apps built with JavaScript employ ample vendor prefixes (for example, -ms-grid, -flexbox and so on) so that the most technologically advanced CSS is available to use in apps. Other high-tech CSS you’ll find in a WinJS app are CSS3 RGBA colors, Web Open Font Format (WOFF) fonts and media queries.

Style WinJS Controls with CSS

WinJS controls are extensions of HTML elements, so you style WinJS controls with the CSS just as you would any HTML tag. The Visual Studio project templates contain references to the CSS that creates modern UI styles for every HTML element and WinJS control, in both dark and light flavors. Of course, you aren’t bound to these styles and are free to modify them as you see fit to complement your company or product branding or theme. However, it’s important to maintain a consistency with the new Windows UI so as not to confuse users.

Figure 1 demonstrates the code for several basic and common HTML and WinJS controls using both the dark and light themes, respectively. Figure 2 shows the output of this code.

Figure 1 The Code for Basic HTML and WinJS Controls

<div id="grid">
  <div style="-ms-grid-column: 1; -ms-grid-row: 1">
    <label for="textbox">Textbox:</label>
    <input id="textbox" type="text" />
  </div>                   
  <div style="-ms-grid-column: 2; -ms-grid-row: 1">
    <label for="button">Button:</label>
    <button id="button" value="Button">Clickety Click</button>
  </div>
  <div style="-ms-grid-column: 1; -ms-grid-row: 2">
    <label for="radio">Radio:</label>
    <input type="radio" id="radio" name="radio" />
      <label for="radio">One</label>
    <input type="radio" id="radio" name="radio" />
      <label for="radio">Two</label>
    <input type="radio" id="radio" name="radio" />
      <label for="radio">Three</label>
  </div>                   
  <div style="-ms-grid-column: 2; -ms-grid-row: 2">
    <label for="select">Select:</label>
    <select id="select">
      <option value="One">One</option>
      <option value="Two">Two</option>
      <option value="Three">Three</option>
     </select>
  </div>                                  
  <div style="-ms-grid-column: 2; -ms-grid-row: 3">
    <label for="rating">Rating:</label>
      <div id="rating" data-win-control="WinJS.UI.Rating"></div>
  </div>
  <div style="-ms-grid-column: 1; -ms-grid-row: 3">
    <label for="toggle">Toggle:</label>
    <div id="toggle" data-win-control="WinJS.UI.ToggleSwitch"></div>
  </div>  
  <div style="-ms-grid-column: 1; -ms-grid-row: 4">
    <label for="datepicker">Date Picker:</label>
    <div id="datepicker" data-win-control="WinJS.UI.DatePicker"></div>
  </div>                     
 <div style="-ms-grid-column: 2; -ms-grid-row: 4">
    <label for="timepicker">Time Picker:</label>
    <div id="timepicker" data-win-control="WinJS.UI.TimePicker"></div>
  </div>
</div>

Common HTML and WinJS Controls in Dark Default Style
Common HTML and WinJS Controls in Light Default Style
Figure 2 Common HTML and WinJS Controls in Dark and Light Default Styles

As you can see from examining Figure 2, the default styles for controls reflect the new Windows UI. A complete listing of HTML and WinJS controls is available on the Windows Dev Center at bit.ly/w1jLM5.

For a detailed look at the WinJS control landscape, see my column, “Mastering Controls and Settings in Windows Store Apps Built with JavaScript,” at msdn.microsoft.com/magazine/dn296546. In the meantime, I’ll look at styling guidelines for a few important controls: AppBars, Flyouts and ListViews.

AppBars AppBars are essential UI components of any Windows Store app. CSS selectors exist for styling every aspect of an AppBar, including the AppBar as a whole, and the individual Button labels, images, and tooltips for both regular and hover states. This means you get total control over the look and feel of AppBars. Once you’ve styled the AppBar itself by overwriting the .win-appbar class, you can move on to the individual commands. Because AppBar Buttons are WinJS controls, the data-win-options attribute contains all the necessary information to properly set up command Buttons by setting the label, icon, section and tooltip properties:

<div id="appbar" class="win-appbar"
  data-win-control="WinJS.UI.AppBar">
  <button data-win-control="WinJS.UI.AppBarCommand"
    data-win-options="{
      id:'addFriend',
      label:'Add Friend',
      icon:'addfriend',
      section:'global',
      tooltip:'Add a friend'}"
    type="button">
  </button>
</div>

You can make the AppBar look vastly different from the simple default stripe across the bottom of the screen by tweaking the styles of the following class selectors:

  • .win-appbar: Styles the AppBar as a whole.
  • .win-command: Styles an individual AppBar Button.
  • .win-commandimage: Styles the command Button image.
  • .win-commandring: Styles the ring around the AppBar Button.
  • .win-commandimage:hover and .win-commandring:hover: Style the command Button image and ring hover states.

As you can see, there are styles for every aspect of the AppBar. 

Flyouts Flyouts are interactive pop-out windows. In Windows Store apps, you usually implement Flyouts to collect user input, often as part of the app’s Settings charm. Flyouts are a great way to implement settings or hold some data the user infrequently accesses. For example, you can use them to provide a privacy statement, required for acceptance of an app into the Windows Store. Styling a Flyout is as easy as overwriting the .win-flyout selector. The system CSS contains settings for .max-width and .max-height, so if you need to collect an entire form of data, you might need to adjust these.

The Flyout is a <div> element that stays hidden and out of sight until the user invokes it from a charm or AppBar command, and then it pops out onto the screen. Though other controls live inside of Flyouts, styling those controls doesn’t change, because they’re just HTML.

ListView Quite possibly the most complex WinJS control, the ListView offers a way to display multiple data items in a grid or list. ListViews also respond to touch and mouse events initiated by the user, allowing the user to select an item or invoke an action. Starting in Windows 8.1, the ListView control lets users drag, drop and reorder items.

Before working with the ListView control, you must know how it works. The ListView control involves four major moving parts: the ListView itself, and the viewport, surface area and items. The items exist inside the surface area, which is the scrollable region of the ListView. The surface area exists and moves within the viewport, so it makes sense that the viewport has the scrollbars, as illustrated in Figure 3.

The Viewport and Its Surface Area Combine to Make the ListView Control
Figure 3 The Viewport and Its Surface Area Combine to Make the ListView Control

Together, the viewport and its surface area full of items form the ListView control. Because the ListView control contains these operationally distinct parts, there are many detailed guidelines for styling it, outlined in the Windows Dev Center at bit.ly/­HopfUg. For now, I’ll look at the most important things to know about styling the ListView control:

  • .win-listview: Styles the entire ListView.
  • .win-viewport: Styles the ListView’s viewport.
  • .win-surface: Styles the scrollable area of the ListView.

These moving parts let you do things such as apply a background image that scrolls along with the items. When the surface area is bigger than the viewport, the viewport shows scrollbars (vertical or horizontal, as needed).

Styling ListView items is straightforward. There are .win-item and .win-container classes to use. Each item in a ListView goes in a container that holds the item’s image and text fields. This container is really just an HTML template defining the elements that join to create an item in a ListView. The code in Figure 4 demonstrates how to define that template and its corresponding ListView. It creates a WinJS.Binding.Template control, which the ListView uses to display data.

Figure 4 Code to Define a Template and Its Corresponding ListView

<div id='listviewtemplate' class="itemtemplate" 
  data-win-control="WinJS.Binding.Template">
  <div class="item">
    <img class="item-image" src="#"
      data-win-bind="src: backgroundImage; alt: title" />
    <div class="item-overlay">
      <h4 class="item-title" data-win-bind="textContent: title"></h4>
      <h6 class="item-subtitle win-type-ellipsis"
         data-win-bind="textContent: subtitle"></h6>
    </div>
  </div>
</div>
<div class="groupeditemslist win-selectionstylefilled"
  aria-label="List of groups"
  data-win-control="WinJS.UI.ListView"
   data-win-options="{ selectionMode: 'none' }">
</div>

As you can see in Figure 4, there are <div> elements that make up the ListView’s item template built into the Grid and Split project templates. At run time, the app’s execution engine injects the .win-container and .win-item classes into these elements, so you won’t see those selectors in the code during development, but you can overwrite them in the CSS file to apply your own styles. In the project template’s ListView code, .item, .item-image, .item-title, .item-subtitle and .item-overlay are all available as selectors you can modify to specify the look and feel of each individual item inside the grid.

No list or grid is complete without the ability to sort, group and perform other actions that affect its members. So of course there are styles for grouped items as well as individual ones. Style the group headings by overwriting the .win-groupheader class selector and show progress in style by overwriting .win-progress.

Fluid CSS Is for Responsive UIs

The Grid, Split and Navigation projects in Visual Studio contain WinJS CSS selectors that work in tandem with HTML5 semantic elements to ensure a fluid and modern layout. The code in Figure 5 shows the CSS and HTML required to create the grid layout from the Grid template. Notice the .fragment class defines rows and columns for a grid using the -ms-grid-columns and -ms-grid-rows prefixes. It then applies these prefixes and other selectors to <div> elements in Figure 5. The semantic <header> and <section> elements clearly define what type of content goes in each.

Figure 5 The Foundational HTML and CSS for a Page Fragment

.fragment {
  /* Define a grid with rows for a banner and a body */
  display: -ms-grid;
  -ms-grid-columns: 1fr;
  -ms-grid-rows: 128px 1fr;
  height: 100%;
  width: 100%;
}
  .fragment header[role=banner] {
    /* Define a grid with columns for the back button and page title. */
    display: -ms-grid;-ms-grid-columns: 39px 81px 1fr;
    -ms-grid-rows: 1fr;
  }
  .fragment header[role=banner] .win-backbutton {
    -ms-grid-column: 2;
    margin-top: 59px;
  }
  .fragment header[role=banner] .titlearea {
    -ms-grid-column: 3;
    margin-top: 37px;
  }
  .fragment header[role=banner] .titlearea .pagetitle {
    width: calc(100% - 20px);
  }
  .fragment section[role=main] {
    -ms-grid-row: 2;
    height: 100%;
    width: 100%;
  }
<div class="fragment groupeditemspage">
  <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">CSS in Windows Store apps</span>
    </h1>
  </header>
  <section aria-label="Main content" role="main">
    <div class="groupeditemslist win-selectionstylefilled"
       aria-label="List of groups"
       data-win-control="WinJS.UI.ListView"
       data-win-options="{ selectionMode: 'none' }">
  </div>
  </section>
</div>

Because this CSS is part of the Grid and Split project templates, you don’t have to worry about taking on the tedious task of creating a fluid grid that changes based on changes in data or the app’s state—it’s built-in.

Windows Store JavaScript app templates use the CSS box model (see my blog post, “A guide to element display and positioning with the CSS Box Model,” at bit.ly/xxATgL) to lay out the page, and the CSS grid layout (see details at the World Wide Web Consortium [W3C] site at bit.ly/14yzx2h) to create a responsive UI. Notice the grid changes to a vertical list and back to a grid upon changing between snap and full views.

Most of the default project templates in Windows Store apps take advantage of CSS media queries to deliver a sophisticated UI that responds to changes in device and browser size, orientation, and resolution. If you want to learn more about media queries, see my blog post, “Create mobile site layouts with CSS Media Queries,” at bit.ly/1c39mDx.

Another reason Windows Store apps make use of media queries is due to Windows 8 supporting four different view states for apps: full, snap, filled and portrait. When users put an app into snap or filled view, it’s conceptually the same as accessing the app from a different device, because both the dimensions and orientation of the browser change quite drastically. 

Upon inspecting the built-in CSS, you’ll find many @media rules for the four app view states as well as for high-contrast and accessible viewing states. Here are media queries that detect snap view and fullscreen-portrait states:

@media screen and (-ms-view-state: snapped) {}
@media screen and (-ms-view-state: fullscreen-portrait) {}

Usually, the same CSS that works for full view works in filled view (three-fourths of the screen) as well. The preceding queries represent the two most popular media features in the realm of Windows Store apps, but there are many more media features on the W3C site at bit.ly/gnza0F.

Windows Store Apps Use Efficient and Organized CSS

Look at the Visual Studio templates’ built-in CSS selectors and you’ll notice they’re sharp and precise. Specificity in CSS (in any code, really) results in easier-to-maintain and better-performing apps. When you see “.fragment header[role=banner]” in code, you know exactly to which elements it applies—in this case, a <header> element that has a role attribute with a value of “banner” inside an element classed as “fragment.” Keep in mind that browsers parse CSS from right to left, so the most specific selectors should go on the right side so the browser can find the matching DOM element faster.

Rather than using script to toggle visual indicators, taking advantage of certain CSS features such as pseudo-selectors for hover, active, disabled, enabled and other visual states ensures easier maintenance. WinJS defines pseudo-selectors as needed for many controls. For example, TextBoxes and CheckBoxes can switch between disabled and enabled states, and anchors can switch between hover and active states. There are even more CSS animations in Windows 8.1 (bit.ly/KDVSPU), so check them out before turning to JavaScript to do the same animations.

Efficiency means proper file organization as well as efficient code. A file named default.css lives in the \css folder, and all built-in HTML pages contain references to it. The CSS you see in Figure 5 lives in this file, alongside regular style rules as well as media queries. You can modify or delete default.css, unlike the ui-dark.css and ui-light.css files.

Visual Studio project templates organize files into folders that contain related items, such as groupedItems.html, grouped­Items.js and groupedItems.css in the \pages\groupedItems folder alongside other similar structures. You can continue to organize files into folders this way, but you can also rearrange the files in any way you’d like. Perhaps you’re reorganizing the project structure because you want to try using the Model-View-ViewModel (MVVM) pattern, and in that case, CSS files could go into a different folder. Maybe you want to toss all the CSS into one folder instead. It doesn’t really matter, so long as your file organization makes sense for your project and it’s easy to maintain.

For readability’s sake, break out CSS into separate files arranged by their functionality or features. For example, you might have CSS for a single control used by many pages, such as a Flyout. That file can go in a folder for common CSS or it can go in the same folder as the Flyout. There’s nothing worse than plowing through a CSS file filled with CSS that has nothing to do with the pages that reference it. For example, CSS that meets the following criteria deserves its own file:

  • CSS for a specific Flyout control or settings page.
  • CSS containing just colors and aesthetics, as this allows you to create themes. You can then swap in and out CSS files like color swatches on an as-needed basis.
  • CSS in media queries for a specific scenario such as snap or filled views. This CSS can go in its own file in the same directory as the page that references it.

This way you can use each functional unit of CSS as you need rather than having to load all the CSS for every page whether the page uses the CSS or not. Remember, these are only guidelines and every project is unique and may have different needs.

Windows Store app projects execute code that’s local to the device rather than downloading the CSS or script first, so there’s no need to bundle and minify CSS and scripts like you would in a Web project. Of course, the app must load the code into memory before executing, so you still want to avoid bloated code for performance and readability reasons.

Focus on Building the App

Styling the many built-in WinJS controls is a snap because the framework provides cutting-edge CSS3 and HTML5 features. The core CSS in WinJS creates a modern, fluid and flexible UI that responds to changes in app view state when the user switches between full and snap views. Having the core WinJS CSS available out of the box means you can focus on building the app rather than fiddling with structural CSS to create a modern-style UI.


Rachel Appel is a consultant, author, mentor and former Microsoft employee with more than 20 years of experience in the IT industry. She speaks at top industry conferences such as Visual Studio Live!, DevConnections, MIX and more. Her expertise lies within developing solutions that align business and technology focusing on the Microsoft dev stack and open Web. For more about Appel, visit her Web site at rachelappel.com.

Thanks to the following technical expert for reviewing this article: Eric Schmidt (Microsoft)