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'"/>
Reusing an SVG button on the same HTML page
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>
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>
The button text is OFF.