Custom AppBar Sprite Icons for your Windows 8 Metro Style HTML app

Well, in Win8 I've kept some of my Globalization stuff, but I've also been working hard on the AppBar, Flyout, Menu, and SettingsFlyout for HTML Metro Apps, which goes a long way to explaining why I haven't been blogging about Globalization so much in the last bit...

You can find appbar documentation on MSDN (http://msdn.microsoft.com/en-us/library/windows/apps/br229670.aspx), and samples and stuff, so I'm going to whiz right on by and assume you've seen (or can look up) a little bit of that. Or for a quick dive in, you can open Blend, make a new HTML Metro App, go to the assets tab, and drag an AppBar onto your project. You can also drag additional AppBar Command Buttons onto that appbar. I'm going to talk about the glyph on those buttons.

If you click on an AppBar button in the designer, you can see an icon drop-down from the HTML attributes panel. That provides a lot of icons to chose from in-box. (So many they're even organized into groups). That's great, and it's best to use the icons there if one's appropriate for your app. But we all know that sometimes there just isn't going to be an in-box icon that's right for you. In those cases you can specify your own image.

We considered lots of different ideas for how to specify custom images, and where we ended up was using sprite. (Trust me, there were lots of discussions and other good approaches, but this one is what we landed on 🙂

The base size of the image is 40px x 40px, and there're 2 rows of 4 images. The 1st row is the normal button state, and the 2nd row is the toggled/selected state for toggle buttons. (If you don't use a toggle button with the image, you don't need the 2nd row). The columns are the rest, hover, active (pressed), and disabled states.

Here's an example of an image intended for a dark theme (matching the accept icon). I stuck it on a cyan background so you can see the white parts 🙂

AppBarCommand draws the "ring" and "disc" parts of the button, so all you need is the actual icon itself. The rest should be transparent so you can see the disc and ring parts. Also, we expect that you know if you're using ui-dark.css or ui-light.css and design your sprite appropriately, we don't try to magically invert the colors for you.

Here's what that sprite above would look like actually rendered (remember, the ring and stuff are added by the system, this isn't what your source should look like):

You can use whatever tool you want to create the sprite, but it needs to support transparent backgrounds (paint.net is one that's easy to find, but pay-apps have more features).

The colors are normally, black 000000, white FFFFFF, and gray 666666 for disabled. Normally I use a png.

One of the really nifty things about it being a sprite is that the rows don't have to be the same image, like volume and mute icons. Or a game could have wrapped and unwrapped packages for unselected and selected toggle states. A "bomb" icon could have a fuse get lit on hover and exploding on pressed. That's part of why we didn't try to combine the first two columns, or just flip the top and bottom for light and dark themes, or pick and chose for the rest/unselected vs pressed/selected states.

Also, since it's a sprite, your icons can be colorful, like the Barnyard Mahjong game. Note that we draw the image on top of the ring, which is a css background/border, drawn by the win-ring class.

Since the sprite is just a png, all of the normal resource loading stuff applies. You can tag them appropriately so that one gets loaded for English and a different one for Arabic. You can also create versions for high DPI mode and for high contrast mode for accessibility.

Hope this helps you build some wonderful icons for your HTML Metro App!

You don't even go into how to actually get the sprite into the code so that it comes up on the appbar. But, thanks for letting us know that sprites are behind the scenes . . .uh. . . I guess? I love, also, how you wrote:

"(Trust me, there were lots of discussions and other good approaches, but this one is what we landed on :)"