This tutorial will walk you through creating a three-state button image that can be used in combination with CSS to create a similar button effect used by a standard Windows (and I assume Mac OS) button. I've chosen to create a button that looks just like one used by Windows Vista Aero but goal is to show how it can be done - don't be put off by my lack of imagination. There are any number of different images, shapes, colours to use when creating the same functionality.

The image below is of the SVG file with all three button states. Over the course of this tutorial we'll be building the file that displays this image.

Getting Started

In order to get the SVG images to render on your machine you need to register Svg.Web.SvgHandler to ensure that all requests made to *.svg files are picked up by the Svg.dll assembly.

(Note: In Visual Studio Development Server this is all you need to do. If you're running IIS7 you'll have to register the handler in the <system.webServer> section. If you're running in IIS 5/6 you'll need to add *.svg files to be handed by the ASP.NET worker process.)

<httpHandlers>
<add verb="GET" path="*.svg" type="Svg.Web.SvgHandler, Svg"/>
</httpHandlers>

Creating the image

We'll start off by creating a simple rectangle representing the default button view.

 <?xml version="1.0" encoding="utf-8" ?>
 <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="246" height="25">
 <rect width="80" height="22" rx="5" x="1" y="1" fill="#eee" stroke="#707070" />
 </svg>

The <svg/> element in the code above is the root of all SVG documents. This element must be the root element of all SVG documents.

Rectangles are represented by <rect/> elements. Why rect and not rectangle? One of the goals of SVG is to create lightweight files - rect is simply shorter and keeps file size just that little it smaller.

The width, height, x and y attributes from <rect/> shouldn't need any explaining but rx, fill and stroke do. SVG supports rounded corners on rectangles and the rx attribute value determines the x-axis radius of the rounded corners and the rx attribute (which I haven't specified - ry takes the value of rx if it hasn't already been specified) determines the y-axis radius of the rounded corner.

The fill attribute allows a hex (e.g. #f00), rgb (e.g. rgb(255, 0, 0)) or colour name (e.g red) to be specified. The stroke attribute allows the same values.

Knowing all this we know that the above is a light grey rectangle, 80 pixels wide, 22 pixels high with rounded edges 5 pixels in diameter. To create the three button states we need to add another two <rect/> elements to the document. They simply need to be positioned in the adjacent to each other in the same fashion above (you can out the positions pretty easily).

Text can be added using the <text/> element and placed using the x and y attributes. "Hello!" will do just fine for now. Now we can create three text elements with the same text or we can create the text element once and reuse it later on in the document.

   <?xml version="1.0" encoding="utf-8" ?>
   <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="246" height="25">
     <defs>
       <text text-anchor="middle" id="buttonText" fill="black" font-family="Verdana" font-size="12" y="16">Hello!</text>
     </defs>
     <rect width="80" height="22" rx="5" x="1" y="1" fill="gray" stroke="#707070"/>
     <rect width="80" height="22" rx="5" x="83" y="1" fill="gray" stroke="#3C7FB1"/>
     <rect width="80" height="22" rx="5" x="165" y="1" fill="gray" stroke="#2C628B"/>
     <use xlink:href="#buttonText" x="40" />
     <use xlink:href="#buttonText" x="122" />
     <use xlink:href="#buttonText" x="204" />
  </svg>

All that's left is to add a little gradient here and there and add some strokes of various colours. Gradients are created by defining a <linearGradient/> element with two or more <stop/> elements. Any colour can be specified and an offset can be specified - this allows use to control where the colours begin and start to fade. I won't go into much detail here as you'll be able to fiddle with this yourself pretty easily.

   <?xml version="1.0" encoding="utf-8" ?>
   <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="246" height="25">
    <defs>
       <text text-anchor="middle" id="buttonText" fill="black" font-family="Verdana" font-size="12" y="16">Hello!</text>
       <rect id="innerGlow" width="78" height="20" rx="5" x="2" y="2" fill-opacity="0"/>
       <linearGradient id="button" x2="0%" y2="100%">
         <stop stop-color="#F1F1F1" offset="47%"/>
         <stop stop-color="#D1D1D1" offset="50%"/>
       </linearGradient>
       <linearGradient id="buttonOver" x2="0%" y2="100%">
         <stop stop-color="#E7F4FB" offset="47%"/>
         <stop stop-color="#C3E3F6" offset="50%"/>
       </linearGradient>
       <linearGradient id="buttonDown" x2="0%" y2="100%">
         <stop stop-color="#DDF0FA" offset="40%"/>
         <stop stop-color="#78BDE2" offset="50%"/>
       </linearGradient>
     </defs>
     <rect width="80" height="22" rx="5" x="1" y="1" fill="url(#button)" stroke="#707070"/>
     <rect width="80" height="22" rx="5" x="83" y="1" fill="url(#buttonOver)" stroke="#3C7FB1"/>
     <rect width="80" height="22" rx="5" x="165" y="1" fill="url(#buttonDown)" stroke="#2C628B"/>
     <use xlink:href="#buttonText" x="40" />
     <use xlink:href="#buttonText" x="122" />
     <use xlink:href="#buttonText" x="204" />
     <use xlink:href="#innerGlow" stroke="white" />
     <use xlink:href="#innerGlow" x="82" stroke="#30D5FE" />
     <use xlink:href="#innerGlow" x="164" stroke="#9EB0BA" />
  </svg>

Okay, so how do I use it?

This next part is a little XHTML and CSS. There are likely multiple ways to achieve this (especially in XHTML) but I'm going to keep things pretty simple. The XHTML is an <a/> element with a class.

   <a class="svg-button" href="SimpleButton.aspx">Hello!</a>

With the XHTML in place we add the CSS that creates the three-state effect. There are probably a couple of different ways of doing this; some may not use a large negative indentation to hide the original link text for accessibility reasons. The perfect CSS for achieving this is beyond the scope of this post.

 .svg-button
 {
      background: url(button.svg);
      padding: 0;
      margin: 0;
      display: block;
      width: 82px;
      height: 24px;
      text-indent: -9999px;
 }

 .svg-button:hover, .svg-button:focus
 {
      background-position: 50% 0%;
 }

 .svg-button:active
 {
      background-position: 100% 0%;
 }

Conclusion

I've kept this post pretty vague. I'm not going to recreate the documentation from the W3C site and I recommend you go there to learn more. My intention is to give a bit of a taster of what SVG is all about and how it can be used. Not only that but this post should let you see how easy it is to use the SVG rendering software.

Last edited Oct 18, 2008 at 2:25 PM by davescriven, version 4

Comments

No comments yet.