Introduction

I really liked the look of the round glassy button style in Windows Vista ever since I installed it. The great thing about WPF is that it allows styling virtually any user interface component. After playing a while with Microsoft Expression Blend, I came up with a style that, in my opinion, looks pretty much like the style I was after. So, I thought I might share it. As I said, I've used Microsoft Expression Blend to draw the button, I've also used the great XAML editor - Kaxaml - for some fine tuning.

Overview

The glass button style consists of three layers, which form the glass effect, and a ContentPresenter to hold the content of the button. All the layers are laid out in a grid, on top of each other. There are also triggers defined, for mouse over and pressed states of the button, to add some interactivity.

I've defined a keyed window resource with the style, but the key can be removed to apply the style to all the buttons in the window.

OK, let's go through each of the layers to see how this cool glass look, widely used in Microsoft products, is achieved.

Button Layers

Background Layer

The first layer is an ellipse which is actually the canvas for drawing the reflection and the refraction layers. Nothing fancy, the fill color of the ellipse is wired to the Background property of the button.

Here is the screenshot of the Blend workspace with a dark blue ellipse:

Refraction Layer

The second layer imitates a refraction of light falling from top to bottom of the button. The reason this layer is being drawn before the reflection layer is that the reflection layer must have a hard edge somewhere in the middle of the button ellipse, to get the shiny glass look. This layer is actually another ellipse, but this time, we will use a radial white-to-transparent gradient fill, to imitate the light refraction. The gradient starts from the bottom middle, and goes to the top middle of the ellipse; however, to decrease the intensity of the refraction highlight, the gradient starts way below the bottom edge of the ellipse. This can be clearly seen on the screenshot and the XAML code below:

Reflection Layer

The third layer is the light reflection layer, which is, actually, the hardest part of the effect. The problem is that the reflection cannot be drawn using any of the standard shapes. So, I decided to use a Path to draw the region of the reflection. Of course, it is possible to draw the path manually, but, frankly, this is not something somebody may enjoy (unless you are an artist and have a nice digitizer). Anyway, I drew yet another ellipse in MS Blend and converted it to a Path, then I just played around with Path Bezier points to get the final smooth path. The good thing about the Path is that you can apply the gradients to a complex Path object, exactly like you would do for any other predefined shape primitives like Ellipse or Rectangle. So, to get the shiny reflection, we will need a transparent-to-white radial gradient fill, starting from the bottom of the path (somewhere in the middle of the button) up to the top edge. I guess if I was an artist, I would be able to formalize the gradient stop for the radial gradient. But, I'm not an artist, so I kept playing with the settings in Blend, until I got the look I was happy with. And, since we have our button laid out in a grid, we should set VerticalAlignment="Top", so the reflection region doesn't end up in the center of the button.

Finally, I added a ContentPresenter to the center of the button. Some experiments show that moving the content area down for 1 pixel gives a more nice looking button, so a margin is also applied to the ContentPresenter (remember that, since the content area is centered in the grid, the top margin of 2px is actually moving it down by a pixel).

OK, here is the final look of the glass button in the Blend workspace:

Adding Some Interactivity

Now, let's add some interactivity to our button.

Mouse Hover Effect

To get a mouse over effect, we will need to increase the intensity of the light source. To do so, let's define a trigger for the IsMouseOver event, copy-paste the gradient setting for both the reflection and refraction layers, and fine tune the gradient alpha values and offsets to highlight the button. For the refraction layer, I just moved the source of the radial gradient a little bit higher, whereas for the reflection layer, I changed the gradient stops to be less transparent white.

Mouse Pressed Effect

For the IsPressed event, we will need to decrease the highlights. So, we need to move the reflection layer light source (radial gradient start point) a little bit down, and for the reflection layer, we need to make the gradient stops more transparent, to dim the light falling on our button.

Again, the values for the gradient stops have been chosen experimentally, I cannot give any exact values for getting the glassy look.

Using the Code

To use the style, just merge the style resource defined in the GlassButton.xaml file with the resource of your Window or Page and set the style of the button to {StaticResource GlassButton}. To set the color of the button, use the button's Background property:

Share

About the Author

I'm a developer focusing on Quality Assurance at the Virage Logic Corporation.
My main responsibilities include the development and maintenance of an environment for automated quality assurance of the Verilog IP provided by our company.

I am try to create some buttons and logo for the company and company application I am work on. I see microsoft site show how to use Expression Blend and WPF to create image.
I search for how to use Expression Blend and WPF and find your article. I see your article was so great. I like it very much and try it in my WPF program.

Can I written you "prior written consent of the Author." so I can modify your application into my to creat logo and button?

There is no dll to use in your app, just read the "Using the code" section.
You'll just need to merge the style resource defined in the GlassButton.xaml file and set the style of your button to {StaticResource GlassButton}.

I came accross your article and I think the application of Styles that show here is great. I'm curious about what modifications would have to be made to make this Silerlight 2.0 compatible.

So far I'm having problems with the fact that the ResourceDictionary.MergedDictionaries feature doesn't seem supported so I went ahead and pasted the the resource XAML for GlassButton to my UserControl.Resources directly (yuk). Unfortunately it also appears that some of the features used within the style such as BezierSegment.IsSmoothJoin and Triggers are also not available.

Thanks for the tips - I'm a programmer, not much of a visual person, but am about to start a project that means I'm starting on wpf and have to have "pretty" buttons etc - this article will help alot so thanks again.

There are a few blog posts already which provide glass effects for WPF buttons. However, what makes your article stand-out is that you describe the process of building up this button style rather than just providing a big lump of XAML.