SVG Buttons in HTML (or SVG Integration in HTML)

It’s been awhile since I posted to this blog. I have been very busy getting the new edition of my Inkscape book ready for the publisher. I wanted to add a new tutorial on using SVG in HTML given that SVG is an integral part of the upcoming HTML5 standard and that IE will finally support SVG. Writing this tutorial turned out to be a lot more difficult than I had anticipated. Not only is there not a lot out there on how SVG fits into HTML5, but there are still major issues to be addressed by the standards groups.

I wanted to start out the tutorial by creating a button that could be used as a better PNG. From there I planned to add functionality to the button such as keeping track of its state (i.e. is it on or off?). I also wanted to be able to style the button from HTML. An evolving web page documenting my trials and findings can be found at my Button Test page. Here I will just cover a few of the most important things I learned.

Using an SVG as a better PNG

The first problem I ran into is how to provide a PNG fallback for browsers that don’t support SVG. I wanted to simply replace a PNG button by an SVG button inside an <a> tag. The normal way to provide a PNG fallback is to use the <object> tag:

  
	<a href="http://tavmjong.free.fr/">
	  <object type="image/svg+xml" data="buttonA.svg">
	    <img src="buttonA.png" alt="A sample button."/>
	  </object>
	</a>
  

But this doesn’t work (except in IE9 beta) as the SVG “swallows” the mouse
clicks when the button is pressed. They never bubble up to the <a> tag. This is probably by design for security reasons.

Cameron Cameron McCormack from the SVG working group suggested using an error handler on an <img> tag. This does work (at least in IE8). So the first problem has been solved:

  
        <a href="http://tavmjong.free.fr/" target="_blank">
	  <img src="buttonA.svg" alt="A sample SVG button."
	       onerror="this.removeAttribute('onerror');
			this.src='buttonA.png'"/>
  


Ansample SVG button.

Reusing an SVG button on the same HTML page

After I added some functionality to the button via JavaScript (making it keep track of two different states), I faced the problem of how to reuse the button on the same page. When a button is clicked, the SVG script needs to notify the HTML script which instance of the button has been activated. At first it appeared that I would have to move the JavaScript code out of the SVG file and into the HTML file, as well as use an inline SVG wrapper to reference SVG fragments in the external SVG file. Erik Dahlström, also of the SVG working group, suggested that using window.frameElement.id inside the script in the SVG file would let you know which button was pushed. This id can then be passed to the script in the HTML file. This works quite well.

This idea also lead to solving another problem: how to style the button from HTML. The SVG standard has a currentColor attribute/style parameter so one would think that one could specify the color in the <object>’s style attribute and the SVG file would pick it up. The SVG standard indicates that this is exactly the purpose of currentColor. Nope. CSS styling doesn’t work across document boundaries. But it is easy to get the color by using window.frameElement.style.color and then setting the button color in an init() function. One can go further. One can customize the text on the button by using <param>s inside the opening and closing <object> tags. The <param>s can also be grabbed by the SVG init() script. Here are two buttons using the same SVG file:

Style from CSS (inside SVG) and custom text from <param>s:

  
    <object type="image/svg+xml" data="buttonG.svg" id="default">
      <param id="TextOn"   name="TextOn"  value="Green" />
      <param id="TextOff"  name="TextOff" value="Red" />
    </object>
  

If you don’t see a button:
go to http://tavmjong.free.fr/blog/

The button text is OFF.

Style from <object> and custom text from <param>s:

  
    <object type="image/svg+xml" data="buttonG.svg" id="pink" style="color:pink">
      <param id="TextOn"   name="TextOn"  value="I am on" />
      <param id="TextOff"  name="TextOff" value="I am off" />
    </object>
  

If you don’t see a button:
go to http://tavmjong.free.fr/blog/

The button text is OFF.

This entry was posted in SVG, Uncategorized and tagged , , , . Bookmark the permalink.

Comments are closed.