Styling windows 8 – 4 The button

As I said in my last post I’m about to dig down into one of my favorite controls, the button. It may seem like something simple but in all it’s simplicity it’s a great control to begin with. Just copying the template and start playing with it is a good start to learn styling.

Also I’ll clear up some of the fog around using different kind of graphics. So we have now reached the forth part in the Styling Windows 8 series:

Styling windows 8 – 1 Colors and themes
Styling windows 8 – 2 Text and font styles
Styling windows 8 – 3 Implicit and explicit styling
Styling windows 8 – 4 The button

Why the button?

As I wrote, it’s a good control to start with when you are learning control styling. You can easily see how the control is constructed with a border and a content presenter. Also, reflecting over all the different visual states; one differences between Windows 8 and Windows Phone is that you have more input variations (touch, mouse, keyboard and pen vs. just touch). Because of that, you need a bit more states for each control:

  • Base (the basic design state)

The common states

  • Normal (unfocused, enabled, no pointer over)
  • Pressed (touch , pointer  and pen down, space/enter on keyboard)
  • Disabled (no focus, no pointer over, no pressed state, just “dead”)
  • Pointer over (pointer hover, pen “hover” )

The you have the additional keyboard only states:

  • Unfocused (basically the normal/base states)
  • Focused (when it’s a click target using enter/space)
  • PointerFocused (hover with a pointer and at the same time its focused)

The invisible button

In Windows Store (metro) apps there is a principle that I think is very important. The content is the driving force of your application and that implies that a lot of what you see in an application will have to be navigable.

For starters I often create an unstyled button style, removing all borders and overlays and add a minimum of styling. Keeping the focus state, very subtle hover animation and press animation, I also the transparent border to make sure that the touch area is as big as possible.

I the use a button with this  button style as container for my navigable elements and that gives me a lot of benefits.

  • You get all the input possibilities for free and can use the click value to handle actions.
  • You get all the visual states from above.
  • You get the benefit of commanding

Using graphics

Using text in buttons is easy enough, just add it to the content and you are all set. But how about graphics? Sure but now you have to decide what to use:

  • Glyphs from the Segoe UI Symbol font
  • Vector graphics – XAML or SVG depending on the project type
  • Transparent PNG files

Segoe UI glyphs

If you are lucky you can use a glyph from the Segoe US Symbol set, those are well designed and available directly in the system. However, don’t ever try to take a shortcut here, if the symbols doesn’t match your task you have to go elsewhere for your graphics.

Using the glyphs is super easy. I bring up the Character Map in windows, find the right symbol, double click and copy. Back in blend I go to content property and paste it and the set font to Segoe US Symbol.  Now adjust the symbol placement and your done!

Vector graphics

For custom icons its best to use use vector graphics. Personally I like to use Illustrator to create the designs. Unfortunately, in the Blend for VS2012 version you cannot directly import Illustrator files (yet?). Currently, I use Blend 4 to import and then copy/paste that code into Blend 5, quite easy. As long as you have simple paths in your application you can even store those paths as resources, making it dead easy to reuse. Lets take this simple piggy bank icon:


The first thing you notice is that this is a bit complicated as graphics, you have the canvas and two paths that has to be handled. So first we do some cleanup, in this case we want to combine the two paths to one single path:


This simplifies your life. We can now add that path data as a named string to our resources.

M13.057625,7.3027134 C11.460352,7.2797151 9.8894787,7.7239256 8.6513071,8.5283356 C8.6513071,8.5283356 8.6222448,9.6181135 8.6513071,9.5999622 C9.5033846,9.0737247 13.352736,7.281301 17.13694,9.5999622 C17.180046,9.6251745 17.167013,8.5475016 17.13694,8.5283356 C15.896893,7.7070436 14.466982,7.3230062 13.057625,7.3027134 z M13.365767,5.9999943 C18.632565,5.9999943 23.053312,9.0626488 24.373524,13.222113 L24.940895,13.123326 C25.212566,13.076947 25.474205,13.262445 25.522308,13.53664 L25.992462,16.275694 C26.040569,16.552917 25.853115,16.815022 25.582455,16.862415 L24.691296,17.015642 C24.253235,20.029903 22.220295,22.615713 19.33728,24.136942 L19.33728,25.456568 C19.33728,26.309423 18.649605,26.999994 17.800556,26.999994 C16.951492,26.999994 16.264812,26.309423 16.264812,25.456568 L16.264812,25.266039 C15.33757,25.47472 14.369213,25.596703 13.365767,25.596703 C12.336273,25.596703 11.34586,25.464628 10.397556,25.245872 L10.397556,25.456568 C10.397555,26.309423 9.7108898,26.999994 8.860816,26.999994 C8.0127621,26.999994 7.3240919,26.309423 7.3240919,25.456568 L7.3240919,24.101671 C5.5197039,23.12883 4.0511389,21.73966 3.1108499,20.085342 L2.8081121,20.12466 C1.5059519,20.287977 0.31906176,19.356485 0.15666437,18.04895 L0.018327713,16.937006 C-0.14305973,15.627471 0.77917957,14.431845 2.0823498,14.268528 L2.0993891,14.266513 C2.3640399,12.82492 2.9955645,11.488158 3.9077849,10.32782 C3.3013153,9.6009779 2.3580132,7.5666018 2.6437116,7.4274817 C3.6752253,6.9254408 5.0275106,7.5111632 6.180306,8.1986866 C8.1410799,6.8276539 10.636142,5.9999943 13.365767,5.9999943 z M13.000484,0 C16.313274,0 18,2.7455041 18,4.9651613 C18,4.9983892 16.477642,5.0130496 16.475685,4.985683 C16.399385,3.0191731 14.975842,1.4572911 13.000484,1.4572912 C11.020259,1.4572911 9.5849667,3.1853282 9.5849676,4.985683 C9.5849667,4.9954662 7.9999986,5.011096 7.9999986,4.9651613 C7.9999986,2.7455041 9.6867228,0 13.000484,0 z

Don’t mind all the data points :) you don’t ever want to dig into that. Now go ahead and reuse it anywhere in our application like this:

The fill property makes it super easy to change color and transparency to the icons and it will always look as good as possible whatever screen resolution you have. Like this:


If you want Creative Commons licensed graphics I suggest looking into what Austin Andrews (aka Templarian) has created. There are a big set of very well designed icons. Beside the light and dark PNG files they are also defined in both SVG and XAML so you can use it right away in your project. Use them in the above scenario to build up your icon library for the application.

Transparent PNG

I would say this is the last resort, mind that if you go down this path you have to design icons for each and every color you want to use, various states as point over, focused, pressed, etc also need to be supported instead of just manipulating the Fill property of a path. Additionally you have to make them in three different resolutions 100%, 140% and 180%, to support screens with higher DPI. So please avoid this one.

Adding the graphics to a button

There is one more thing to get the vector data to work properly in a button though. You can’t just set the Forground property and expect the graphics to follow as it uses a Fill property for color. Tim Heuer have a great little post around this issue. Using that as as an inspiration I can add to my unstyled button code and reuse the Path data resource to get this simple button definition:

This is really nice, now you can do all sorts cool stuff on thus, setting the color as usual and keep all the normal behavior of the button. For the complete button style I use and sample on how to use it look in the GroupDetailPage and the UnstyledGraphicsButtonStyle in ThemeStylse.xaml in my InStyle sample application v5.

This Post Has 4 Comments

Leave a Reply