Page Navigation in Windows 8 JavaScript Apps

I’d like to talk a bit about navigating in Metro apps using HTML/JavaScript. There are a few options for doing so, and as you probably know whenever there’s more than one way to do things, then you the developer have power but not necessarily clarity. The latter is what I hope to offer here.

First of all, the HTML/JavaScript that Metro apps are based on are identical to the HTML/JavaScript that websites are based on. It is entirely based on the standards. This is good because proprietary things are bad - generally speaking. This means that you can navigate exactly like you do in websites, but don’t. I’ll explain why not.

So you could navigate from default.html to page2.html like this…

<a href="page2.html">link to page 2</a>

But again… you should usually do this. Doing so changes the “top level document location”. This navigation looks something like this…

Where the user is no longer on the default.html page. For websites, it’s just fine to jump around by navigating the top level like this because you’re usually not too concerned about state, but in a full-fledged application, you usually are concerned with state and you can make your life easier by using the built-in navigation features that are provided by the VS2012 templates.

When you use the navigation functionality, a navigation looks more like this…

Notice that the user is still on default.html, but the contents of the second page have simply been loaded into what is called the contenthost. Now, if you loaded a bunch of script and styles on default.html and even declared some variables and set some state, you still have all of that, even though to the user it appears that you’ve navigated to a second page.

Implementing this is pretty straight-forward. Follow these steps…

  1. Get the navigate.js script file that comes with the Navigation Application project template in VS2012. You can either start with the Navigation Application project template and notice that navigate.js is already in your js folder, or you can create a throw-away Nav project and steal that file.

  2. Reference the navigate.js from your default.html file…

  3. Add a contenthost to your default.html file

And that’s it. After this has been implemented, then you are free to do things in your JavaScript like this…

WinJS.Navigation.navigate("/pages/page2/page2.html");

And you have the chance to pass some parameters without having to resort to query string parameters which can be cumbersome and restricting. To do this, you can pass a second parameter to the navigate function like this…

WinJS.Navigation.navigate("/pages/page2/page2.html", myDoohicky);

…where myDoohicky can be any JavaScript object you want.

Now, when might we actually perform this navigation? Well, in many cases it will be on some user action. For instance, let’s say the user is going to click a button and we want to navigate them to page2.html. Let’s see what that would look like…

HTML

<button id="myButton">go to page2</button>

JavaScript

ready: function (element, options) {
document.querySelector("#myButton").onclick = function (args) {
WinJS.Navigation.navigate("/pages/page2/page2.html", "test value");
};
}

Now let’s look at a bit more pragmatic example. Let’s say we are working in a grid (WinJS.UI.ListView technically) and when the user touches one of the tiles, we want to navigate to a second page with more details about that element.

This can be wired up much like the simple button example above, but likely the elements in our grid are data bound from some list that we have. In that case, perhaps the easiest way to implement this is by adding a function to the list and then bind the click function just like any of the data elements are bound. Here’s an example of that…

HTML

<div id="headertemplate" data-win-control="WinJS.Binding.Template">
<div>
<p data-win-bind="innerText:firstLetter"></p>
</div>
</div>
<div id="template" data-win-control="WinJS.Binding.Template">
<div data-win-bind="onclick:clickFunction">
<img class="img" data-win-bind="src:imageUrl" />
<p class="name" data-win-bind="innerText:title"></p>
</div>
</div>
<div id="list" data-win-control="WinJS.UI.ListView"></div>

JavaScript

ready: function (element, options) {

var titlesListGrouped = new WinJS.Binding.List().createGrouped(
function (i) { return i.title.charAt(0).toUpperCase(); },
function (i) { return { firstLetter: i.title.charAt(0).toUpperCase() }; }
);

var list = q("#list").winControl;
list.itemDataSource = titlesListGrouped.dataSource;
list.itemTemplate = q("#template");
list.groupDataSource = titlesListGrouped.groups.dataSource;
list.groupHeaderTemplate = q("#headertemplate");

WinJS.xhr({ url: "http://odata.netflix.com/Catalog/Titles?$format=json&amp;$top=200" })
.then(function (xhr) {
var titles = JSON.parse(xhr.response).d;
titles.forEach(function (i) {
var item = {
title: i.ShortName,
imageUrl: i.BoxArt.LargeUrl,
clickFunction: function(args) { WinJS.Navigation.navigate("/pages/page2/page2.html", item); }
};
item.clickFunction.supportedForProcessing = true;
titlesListGrouped.push(item);
});
});

}

Now, there’s a lot going on in the JavaScript file there, so let me break it down for you. First of all, I pulled this example from another post I did on creating a Netflix browser app utilizing their OData feed. If you want to know what’s going on with the call and the data binding, go check that out.

I added to it though. I changed what happens in the forEach loop. The reason I did is to illustrate how to bind to a function like you bind any other data property. Look in the HTML at the div just below the one with the id of template. I’m binding the onclick attribute to the clickFunction. That clickFunction is what I created in the forEach loop of the JavaScript. Notice, though, that there’s one funny thing we need to do to it. Since we are using this in the HTML it could be exploited and so we turn on strictProcessing for our app and that requires us to set _supportedForProcessing_ on any functions that we are going to call from the HTML. So, we set that to true for our function and we’re good to go.

I hope this brings the concept home for you. If you have questions, leave a comment below and I’ll be glad to try to help.

Fast Refresh... Nugget!

Hey, Metro developers, if you’re using HTML/JS to build your apps, I have a little golden nugget for you. Actually, it’s possible you already know and I’m the one that’s late to the game. Anyway, have you ever made a little tiny tweak to your HTML structure, a slight mod to your CSS style, or a little enhancement to your JavaScript and wanted to see the change effect immediately instead of relaunching your app each time? It’s a valid desire. My last job was website development and so I’m used to the whole save, switch, refresh workflow.

If you’re working without the debugger attached, then you know it’s not that difficult, you just hit CTRL + F5 again.

If you are working with the debugger attached, however, you might think you have to stop (SHIFT + F5) and then start again (F5). Actually, though, all you have to do is hit F4 (Fast Refresh is how we call that)! Now that’s handy!

How to do Semantic Zoom in an HTML/JS App

Semantic Zoom is super easy, but even the easy things can use some conceptual explanation and examples to clarify them. Rest assured that once you see it, you’ll go “Ah! That won’t be a problem then.”

If you use XAML/C# to make your Metro apps, then you should check out Jerry Nixon’s post on semantic zoom.

So, I’m going to be talking about Semantic Zoom. You know what that is right? It’s different from optical zoom. It’s a Windows 8 differentiator and it’s really helpful. It’s a way of zooming out of some information and making it easier to orient and easier to consume. Optical zoom just scales everything. Semantic zoom shows a different logical version of the same list.

Any given list in a Windows 8 screen may be 3 or 4 or 5 screens worth of horizontal information, right? Well, it’s not hard to pan that far, but it’s not always easy to really see what your scope is when it’s on 4 screens. When a user semantically zooms out, he is hoping to get oriented with your data. He is hoping to rise up so he can understand and/or so he can dive back in at just the right place.

I’m going to provide an example here. My example is a list of attractions in Kauai. Each has a category property - things like Flora, Scenery, Waterfall, etc. I will use these categories to group my list, but with the grouping and all of the content I want to show, the list is about 4 screens wide…

This might be a good scope of data for this view in my app, but at the same time it might be too much to expect a user to be able to consume in a glance. So, we implement semantic zoom. When the user pinch zooms, we want to show them something like this…

This is not very stylish, I know, but it serves to make the point. We want to indicate in much less horizontal space (and hopefully on a single screen) what our data contains. In this case, we’re showing the categories. We could get quite creative with what we show here. The concept is to logically expand our scope to orient the user.

Now when the user chooses the Waterfall tile, he’ll be semantically zoomed back in and will be taken directly to the waterfall section. The user can also zoom back in using a stretch zoom gesture (two fingers on the screen and then moved further apart).

Let’s move on to how to implement this. It’s by no means rocket science. Unless of course you’re building an app for… er… rocket science.

Start off with a blank Metro application. First thing you’re going to need is the data.

In your default.js file, add an onready function like this…

app.onready = function (args) {

};

And then inside of it add your data like this…

var attractions = [
{ name: "Fern Grotto", category: "Flora", location: "East", imageUrl: "http://www.kauai.com/photos/kauai/point/98/super/fern_grotto-kauai-attraction.JPG", description: "Only accessible by boat or Kayak, the fern Grotto is located about two miles up Kauai's Wailua River, the only navigable river in the State of Hawaii." },
{ name: "Hanalei Valley Lookout", category: "Scenery", location: "North", imageUrl: "http://www.kauai.com/photos/kauai/point/51/super/hanalei-valley-lookout-kauai-attractions-3.jpg", description: "The Hanalei Valley is an enchanted site charmed with the likes of countless waterfalls, rainbows, fields of taro and hidden treasures waiting to be explored." },
{ name: "Hanapepe Swinging Bridge", category: "Other", location: "West", imageUrl: "http://www.kauai.com/photos/kauai/point/93/super/843726541306971801.jpg", description: "Located in old town Hananpepe a Historical sight made up of an eclectic group of galleries and shops. Home to Friday night Art walk." },
{ name: "Kalalau Lookout", category: "Scenery", location: "West", imageUrl: "http://www.kauai.com/photos/kauai/point/94/super/3075381091306977440.jpg", description: "The Kalalau lookout stands at 4,00 feet above sea level and gives you a peek at a valley that as late as the 1920's still was the home to residents who farmed crops there. The only way into the valley is by foot along the Kalalau Trail or by boat." },
{ name: "Kauai Coastal Path", category: "Coastline", location: "East", imageUrl: "http://www.kauai.com/photos/kauai/point/100/super/kauai-coastal-path-kauai-attractions.JPG", description: "Kauai Coastal Path is a scenic and and safe place to walk, run or bike while taking in the beautiful scenery of Kauai's East Side." },
{ name: "Keahua Arboretum", category: "Flora", location: "East", imageUrl: "http://www.kauai.com/photos/kauai/point/95/super/keahua-arboretum-kauai-attractions-5.JPG", description: "The Keahua Arboretum is planted with native and introduced plants by the University of Hawaii and is used as an outdoor classroom to students and visitors. Cool off in the cold mountain spring water and enjoy lunch at one of the picnic sites." },
{ name: "Kilauea Lighthouse National Wildlife Preserve", category: "Coastline", location: "North", imageUrl: "http://www.kauai.com/photos/kauai/point/49/super/kilauea_lighthouse_national_wildlife_preserve-kauai-attraction.JPG", description: "Kilauea Point National Wildlife Refuge started in 1985 by the U.S. Fish and Wildlife Service is marked by its towering lighthouse. The ocean cliffs and tall grassy slopes of a dormant volcano provide a protective breeding ground for many Hawaiian seabirds" },
{ name: "Koloa Landing", category: "Coastline", location: "South", imageUrl: "http://www.kauai.com/photos/kauai/point/99/super/koloa-landing-kauai-attractions-2.jpg", description: "Once one of the largest deep water whaling ports in Hawaii, Koloa Landing is now a popular location for shore dives." },
{ name: "Lawai International Center", category: "Other", location: "South", imageUrl: "http://www.kauai.com/photos/kauai/point/110/super/lawai-international-center-kauai-attractions.JPG", description: "Lawai International Center and the 88 Shrines are located on the ancient site of Heiau where Hawaiians once came for healing." },
{ name: "Menehune Fishpond", category: "Other", location: "East", imageUrl: "http://www.kauai.com/photos/kauai/point/48/super/menehune-fishpond-kauai-attractions.JPG", description: "Menehune Fish Pond is located just above the Nawiliwili Harbor. The Menuhune Fish Pond, Alekoko got it's name from the legend that a small race of people known as menehune built these ponds 1,000 years ago overnight." },
{ name: "Napali Coast", category: "Coastline", location: "North", imageUrl: "http://www.kauai.com/photos/kauai/point/82/super/napali-coast-kauai-attractions.jpg", description: "The Napali is a fifteen mile stretch of coastline starting on the north shore at Kee beach and ending on the west side at Polihale beach. This rugged coast will leave you breathless as you gaze upon the he razor sharp cliffs that rise sharply from sea to " },
{ name: "Opaekaa Falls", category: "Waterfall", location: "East", imageUrl: "http://www.kauai.com/photos/kauai/point/88/super/opaekaa_falls-kauai-attraction.JPG", description: "Opaekaa Falls can be seen from the scenic lookout along Kuamoo Road in the Wailua Homesteads. " },
{ name: "Spouting Horn", category: "Coastline", location: "South", imageUrl: "http://www.kauai.com/photos/kauai/point/86/super/spouting-horn-kauai-attractions-1.JPG", description: "Spouting Horn Beach Park is a delightful lookout where you can watch a blowhole spout a plume of sea water into the air." },
{ name: "Tree Tunnel", category: "Flora", location: "South", imageUrl: "http://www.kauai.com/photos/kauai/point/91/super/tree-tunnel-kauai-attractions.JPG", description: "The beautiful canopy of eucalyptus trees line Maliuhi Road, the gateway to Kauai's sunny side and the towns of Koloa, and Poipu." },
{ name: "Wailua Falls", category: "Waterfall", location: "East", imageUrl: "http://www.kauai.com/photos/kauai/point/50/super/wailua_falls-kauai-attraction.JPG", description: "This 140 foot waterfall appears on many postcards, print and media collections and was used as the opening scene for the 1970's Television series Fantasy Island." },
{ name: "Waimea Canyon", category: "Other", location: "West", imageUrl: "http://www.kauai.com/photos/kauai/point/83/super/waimea-canyon-kauai-attractions-2.JPG", description: "Waimea Canyon State Park is the largest canyon in the Pacific and will undoubtedly capture your gaze, with its 10 mile long stretch at a mile wide and measuring more than 3,500 feet deep." },
{ name: "Wet and Dry Caves", category: "Other", location: "North", imageUrl: "http://www.kauai.com/photos/kauai/point/111/super/wet-and-dry-caves-kauai-attractions.jpg", description: "Waikanaloa &amp; Waikapalae Wet Caves are located off the the main road in the Haena State Park and are easy to get to. The Waikanaloa Cave is not for swimming. The Waikapale cave is located a a little further up the road and involves a quick hike to the swim" },
];

And then you need to turn that simple JavaScript array into a Binding List so you can bind to it. Like this…

var attractionsList = new WinJS.Binding.List(attractions);

And then you group that list like this…

var attractionsListGrouped = attractionsList.createGrouped(
function (i) { return i.category; }, //group key
function (i) { return { category: i.category }; } //group
);

And there’s that.

Now, let’s visit your HTML file (default.html).

You’ll need your actual ListView…

<div id="zoomedinlist" data-win-control="WinJS.UI.ListView"></div>

And you’ll also need a template and a header template…

<div id="headertemplate" data-win-control="WinJS.Binding.Template">
<div data-win-bind="innerText:category"></div>
</div>
<div id="zoomedintemplate" data-win-control="WinJS.Binding.Template">
<div>
<img class="item-image" data-win-bind="src:imageUrl" />
<div data-win-bind="innerText:name"></div>
</div>
</div>

And then you need to bind the ListView to your data, so go back to your default.js file and after the var attractionsListGrouped statement, add this…

var zin = q("#zoomedinlist").winControl;
zin.itemDataSource = attractionsListGrouped.dataSource;
zin.groupDataSource = attractionsListGrouped.groups.dataSource;
zin.itemTemplate = q("#zoomedintemplate");
zin.groupHeaderTemplate = q("#headertemplate");

Now you should have a working list, and all we have to do is add the semantically zoomed out version and the semantic zoom control itself.

So, on the default.html page, add the semantic zoom control and the zoomedoutlist to the list you already have like this…

<div data-win-control="WinJS.UI.SemanticZoom">
<div id="zoomedinlist" data-win-control="WinJS.UI.ListView"></div>
<div id="zoomedoutlist" data-win-control="WinJS.UI.ListView"></div>
</div>

(note that last code should be pasted over the existing zoomedinlist since we already had that there)

Then, that zoomedoutlist needs some data binding, so we go back to the default.js and add this…

var zout = q("#zoomedoutlist").winControl;
zout.itemDataSource = attractionsListGrouped.groups.dataSource;
zout.itemTemplate = q("#zoomedouttemplate");

OKAY STOP. Let me explain what’s going on here. Quite simply, we’re just adding two different ListView controls with their own data bindings (that happen to be based on the same data, and then we are wrapping both of those up with the WinJS.UI.SemanticZoom control.

Keep in mind, that there are no constraints necessarily on what can comprise those two lists. You, the developer, are responsible for making sure that your semantic zoom control makes good sense for the user.

Now, please notice that the data source for the zoomed in list is a grouped list of attractions, while the data source for the zoomed out list is a list of groups. Thanks why we get the categories for our zoomed out tiles.

I added a couple of classes in the templates that I had you paste into your HTML, so if you add the following style rules to your default.css file, then that should make everything look sensible…

.item-image {
width: 280px;
height: 210px;
}

.sz-category {
width: 200px;
height: 200px;
background-color: green;
color: white;
font-weight:bold;
font-size: large;
padding: 10px;
}

And that should do it. Leave a comment if this was helpful. Actually, leave a comment if it wasn’t helpful too. :)

Happy zooming.

When to Use ViewBoxes and FlexBoxes

HTML and CSS is great, but there’s at least one thing that has driven web designers mad for ages - layout. We used to use tables and it worked. We knew their weaknesses, but they worked. Then we were told that tables are for tabular data and div elements are for layout, but divs are wretched creatures. To set divs next to each other one had to float them, but then when finished floating had to be explicitly turned off - argh. Also, divs had no notion of filling vertical space or of controlling the vertical placement of anything within it.

So a myriad of web designers resorted to absolute positioning, browser hacks, jQuery UI positioning, or some other means just to get things to go where they ought.

Enter Windows 8.

Windows 8 allows us to design our Metro style apps using HTML and CSS. In doing so, however, it the CSS standards and Microsoft have given us some facilities to finally place things where we want them.

It’s not obvious how everything works though so let me give you a boost. If you start with a Fixed Layout Application (for the record, I think it should be called the Flexible Layout Application) project template you get the right stuff automatically, but here’s an explanation so you have the concept as well.

We’re dealing with two entities here: the WinJS.UI.ViewBox control and the -ms-flexbox css property value (for the display property).

WinJS.UI.ViewBox

The purpose of the ViewBox is stated in the documentation. It says that it “Scales a single child element to fill the available space without resizing it. This control reacts to changes in the size of the container as well as changes in size of the child element. For example, a media query may result in a change in aspect ratio.”

The first thing I had a hard time wrapping my head around was the overlap between a ViewBox and a FlexBox. Then I discovered that there really isn’t any. The ViewBox control is quite simple. It scales the content that it contains but maintains it’s aspect ratio.

It works like this…

Note that it does not work like this…

In other words, as it says in the documentation, it scales the contents, but it keeps their proportions.

And that’s really the end of it. The ViewBox serves this one purpose.

Flexbox

Now it’s time to talk about the flexbox. This is not a WinJS control, but rather an implementation of a CSS3 property. It’s not quite a standard property yet because all of the browsers are still implementing it with vendor specific properties and values, but it’s close. For Windows 8, we specify a display property with a value of -ms-flexbox to indicate flexbox layout.

The purpose and scope of the flexbox is a bit bigger than the ViewBox. Here’s what the W3C spec for the CSS Flexible Box Layout Module says “In the flexbox layout model, the children of a flexbox can be laid out in any direction, and can “flex” their sizes, either growing to fill unused space or shrinking to avoid overflowing the parent. Both horizontal and vertical alignment of the children can be easily manipulated. Nesting of these boxes (horizontal inside vertical, or vertical inside horizontal) can be used to build layouts in two dimensions.”

So, like the ViewBox, we still have the concept of the container’s content changing in size to fit the container, but this has more to do with a collection of child items.

Additionally, the flexbox offers a lot of properties to specify how it’s children are laid out. A quick glance in Blend at the CSS properties on a div in the Flexbox category will enumerate them for you…

Notice first the -ms vendor specific prefix as I mentioned.

To give a thorough description of the possibilities with these properties, I’d be duplicating what’s already done quite nicely on the flexbox page on w3.org, so just go there and read the nitty, gritty detail.

Differences

The ViewBox is a WinJS control, whereas the flexbox is a CSS property.

The ViewBox always acts on a single child item, but the flexbox can act on multiple child items.

The ViewBox itself changes size to fit it’s container as a core feature. The flexbox can be told to scale to 100% either in width or height, but it doesn’t have to.

The ViewBox does not extend control over the alignment and scale modes of it’s contents, but always does the same thing - scales the child item without changing it’s proportion.

All Together Now

Now that you know how different these controls are, consider them together. If you put a flexbox div inside of a ViewBox, you get a really effective layout tool. Try this for your HTML…

<body>
<div data-win-control="WinJS.UI.ViewBox">
<div class="flexy">
<div class="item">A</div>
<div class="item">B</div>
<div class="item">C</div>
</div>
</div>
</body>

With this as the CSS…

.flexy {
-ms-flex-align: center;
-ms-flex-direction: column;
-ms-flex-pack: center;
display: -ms-flexbox;
}

.item {
height: 200px;
width: 200px;
border:solid 1px;
font-size:9em;
}

What you have now is a flexbox that fills its area well. Look at these simulator screenshots so you can see what this would look like…

[more images missing]

XAML is unarguably the most powerful layout engine I’ve ever seen, but I really don’t feel like there’s too much in HTML/CSS that we’re missing now with additions like this. It’s rather empowering.

Happy layouts!

The Ocho

There’s nothing better for learning a new platform, framework, or language than getting together with other people. Shared experience brings not only technical know-how, but also know-how-not-to! I always say that our careers are made of three things: education, inspiration, and experience. You need all three. Education can be rote. You get it from books, videos, classes, etc. Inspiration is the energy and motivation for doing what you’re doing. If you’re not working on a project that is exciting and has the potential to change the world, you might just be a bit bored. Experience then is what you get when you try to do it over and over. You succeed, you fail, but each time you learn how to and how not to do things.

Meeting together with other people is magic because it’s an opportunity to get some of all three of these. You get some training. You get inspired by the content and what others are doing with it. And you get to try things and get experience and you also get to benefit from the experience of others.

So that’s why I started The Ocho. The Ocho is a user group for Windows 8 developers. Whether you’re beginner or advanced, go to http://www.meetup.com/theocho and sign up to visit a local meeting. You’ll learn a lot and you’ll have some fun too. Tell your friends about it, so we can build it up even more.

See you at The Ocho!

Microsoft vs. Apple - Differences in Tablet Philosophy

Microsoft and Apple have a long and tangled past. From most perspectives, the two would certainly be considered competitors, but when fitted with the right glasses (rose) one can also choose to see the two technology giants collaborating to add enjoyment, value, education, and information to the lives of billions. I used to teach high school and there were occasions when both companies made significant donations to classrooms to bring better education to my students.

But right now I want to talk about a fundamental difference in how each company appears to approach the tablet market.

There’s nothing special about a tablet. It’s just a form factor. Phones are this big… tablets are a bit bigger… desktop monitors a bit bigger still. They’re just screens. Sometimes they’re sideways and sometimes they’re upright. Sometimes they’re stationary and sometimes they’re on the move. Imagine for a minute where our children and their peers will find screens - in the kitchen, in the car, on the bus, on the train, and hopefully rolled up in their book bag. Remember… it’s just a screen.

Apple threw some words toward Microsoft recently saying that tablets and desktops are fundamentally different and that attempting to put the same OS on both devices would end up degrading the user’s experience. I suppose Apple is saying this precisely because they have a different OS their tablet than their desktop.

I see the Windows 8 strategy as relieving. It can be nothing but easier for devices to collaborate when they are running the same bits. I have Windows 8 on my TV, on my work PC, and on my tablet. We’re still in beta and already the experience is nothing short of delightful.

I look forward to the many more device form factors that are inevitably to come!

All Windows 8 Quickstarts

If you’re looking for training material for Windows 8, you’ll find quite a lot online. It can be overwhelming finding stuff online though. I consider it part of my job to help you locate things, so here’s a tip. Just do a search in the Windows 8 Dev Center (http://dev.windows.com) for the word ‘quickstart’; and you’ll find a lot of walk-through articles that are really helpful in figuring out how things work. Here’s a link to that search directly: http://social.msdn.microsoft.com/search/en-US/windows/apps?query=quickstart&Refinement=180

Giveaway - Visual Studio Windows Decals

I’m giving away one large (8.5” x 11”) Visual Studio 2012 logo window decal and one small “I heart VS2012” decal. I’m sure these will be all over the place soon, but you can be the first around if you’re the lucky winner.

To enter just follow me (@codefoster) on Twitter and retweet this tweet. I’ll randomly select a winner on June 7.

Art Matters

I’m in a Microsoft building today that I’ve not been in before. There are a lot of them since I’m a relatively new employee. This one houses a lot of the work that goes into the Windows Phone 7 operating system, and that’s pretty cool.

I arrived early for my conference and decided to spend some time meandering. A 3rd floor native told me I should visit the Windows Phone design studio on the 2nd. The design studio looks like a bunch of art supplies, flowers, and rainbows blew up. It’s very cool actually.

I’m a propeller head for sure, so it’s important to me that a system functions correctly, but I want never to forget that art matters. It matters because it’s human like your users. When I picked out my SCUBA gear, for instance, its ability to sustain my existence while I’m under water was certainly high on my priority list, but it was also an assumption for the most part. SCUBA gear wouldn’t likely make it to the consumer shelf if it wasn’t well tested. So I essentially set that aside and look for gear that I enjoy looking at - gear that makes me feel like a Navy Seal Ninja.

Know that your users are making the same assumptions that your application is going to function as it’s intended, and they are going to choose it, keep it, and pay for it based on its art. Is it beautiful? Is it smooth like butter? Is it inspirational.

The Counter Principles of Metro Style Design

Likely you’ve read the Metro style design principles, but you haven’t seen the counter principles yet (because I made them up). Here we go…

1. Show Shame in Mediocrity

To really show shame in mediocrity, just look at about 80% of the apps in any major app marketplace. These apps may get a users attention with a catchy title or a promise to solve some problem, but then they fail to add any value to anyones life. Even if they are not devoid of functional value they fail to provide any user joy.

  • Ignore the little things
  • Do something different in every little user interaction so you can keep them on their toes
  • Embrace chaos
  • Deviate slightly from the grid so the user knows something is wrong even though that can’t see it

2. Flow Like Peanut Butter

To be clear, peanut butter doesn’t flow. Even creamy peanut butter doesn’t flow. To meet this counter principle, perform actions synchronously, use while loops that peg the processor, and only use the UI thread.

  • Add some offset between the user’s finger and the registered touch point
  • No transitions or animations… all straight cuts
  • Add boring graphics and boring interactions.
  • Embrace lag and jitters

3. Be Faux Analog

It’s 2012, but give the user a solid 1994 experience by rendering an actual real-life scene and hope they’ll figure out which drawer their word processor is in. Even though there’s no actual need for a spiral binding, let’s add one. It’s nostalgic.

  • Show a desk or a lobby or some other loose analogy to your navigation model
  • Firmly draw your limits at real life paradigms and scenarios
  • Expand on the success of Microsoft Bob&copy;

4. Do Less With More

Pack that screen. You have millions of pixels at your disposal. You can use some for navigation, some for commanding, and if there’s room left over you can even include your user’s content.

  • Assure that users can orient themselves to your views within 7.5 minutes
  • Adhere to a strict 45 button limit per view
  • Give users a sense of adventure as they discover your application

5. Die Alone

  • Assume the user is only concerned with doing whatever it is that your app does.
  • Assume they don’t have friends to share your content with.
  • Assume they don’t need to find anything of your content
  • Assume the user what’s to do one thing at a time… always… ever… only