SVG In HTML Introduction

  • Revision slug: SVG_In_HTML_Introduction
  • Revision title: SVG In HTML Introduction
  • Revision id: 54275
  • Created:
  • Creator: Gfldex
  • Is current revision? No
  • Comment /* Discussion */

Revision Content

Overview

This article and its associated example shows how to use inline SVG to provide a background picture for a form. It shows how JavaScript and CSS can be used to manipulate the picture in the same way you would script regular XHTML. Note that the example will only work in browsers that support XHTML (not HTML) and SVG integration.

Source

Here is the source to the example:

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <title>XTech SVG Demo</title>
  <style>
    stop.begin { stop-color:yellow; }
    stop.end { stop-color:green; }
    body.invalid stop.end { stop-color:red; }
    #err { display:none; }
    body.invalid #err { display:inline; }
  </style>
  <script>
    function signalError() {
      document.getElementById('body').setAttribute("class", "invalid");
    }
  </script>
</head>
<body id="body"
   style="position:absolute; z-index:0; border:1px solid black; left:5%; top:5%; width:90%; height:90%;">
  <form>
     <fieldset>
       <legend>HTML Form</legend>
       <p><label>Enter something:</label>
          <input type="text"/>
          <span id="err">Incorrect value!</span></p>
       <p><button onclick="signalError();">Activate!</button></p>
     </fieldset>
  </form>
  <svg xmlns="http://www.w3.org/2000/svg" version="1.1"
    viewBox="0 0 100 100" preserveAspectRatio="xMidYMid slice"
    style="width:100%; height:100%; position:absolute; top:0; left:0; z-index:-1;">
    <linearGradient id="gradient">
      <stop class="begin" offset="0%"/>
      <stop class="end" offset="100%"/>
    </linearGradient>
    <rect x="0" y="0" width="100" height="100" style="fill:url(#gradient)" />
    <circle cx="50" cy="50" r="30" style="fill:url(#gradient)" />
  </svg>
</body>
</html>

Discussion

The page is mainly regular XHTML, CSS and JavaScript. The only interesting part is the <svg> element it contains. This element and its children are declared to be in the SVG namespace. The element contains a gradient and two shapes filled with the gradient. The gradient color stops have their colors set by CSS. When the user enters something incorrect into the form, the script sets the invalid attribute on the <body>, and a style rule changes the gradient end-stop color to red. (Another style rule makes an error message appear.)

This approach has the following points in its favor:

  • We have taken a regular XHTML form that could have been part of an existing Web site, and added an attractive, interactive background
  • The approach is backwards compatible to browsers that do not support SVG; simply, no background appears in them
  • It's very simple and performs very well
  • The picture dynamically sizes itself to the required size in an intelligent way
  • We can have declarative style rules applying to both HTML and SVG
  • The same script manipulates both HTML and SVG
  • The document is entirely standards-based

To add a linked image with DOM methods to an embedded SVG element, one has to use setAttributeNS to set href. Like in the following example:

 var img = document.createElementNS("http://www.w3.org/2000/svg", "image");
 img.setAttributeNS("http://www.w3.org/1999/xlink", "xlink:href", "move.png");  
 

Details

The viewBox attribute establishes a logical coordinate system which the SVG picture's coordinates are relative to. In this case our picture is laid out in a 100 by 100 viewport.

The preserveAspectRatio attribute specifies that the aspect ratio must be preserved by centering the picture in the available size, sizing to the maximum of the height or width and then cutting off any overflow.

The style attribute pins the SVG element to the background of the form.

Related Links

  • Another SVG in XHTML example: A swarm of motes
  • Inline SVG page on SVG wiki
  • Working example that works in both Mozilla and in Internet Explorer with Adobe's SVG Viewer installed. (For inline SVG to work in both Firefox and Internet Explorer it is necessary to serve documents with a different Content-Type to each browser. For this reason, if you're behind a proxy server that caches the page, the example wont work in the second browser you load it in because it will receive the wrong Content-Type.)
{{ languages( { "pl": "pl/SVG_w_XHTML_-_Wprowadzenie", "fr": "fr/Introduction_\u00e0_SVG_dans_HTML", "ja": "ja/SVG_In_HTML_Introduction" } ) }}

Revision Source

<p>
</p>
<h3 name="Overview"> Overview </h3>
<p>This article and its associated example shows how to use inline <a href="en/SVG">SVG</a> to provide a background picture for a form. It shows how <a href="en/JavaScript">JavaScript</a> and <a href="en/CSS">CSS</a> can be used to manipulate the picture in the same way you would script regular XHTML. Note that the example will only work in browsers that support XHTML (not HTML) and SVG integration.
</p>
<h3 name="Source"> Source </h3>
<p>Here is the source to <a class="external" href="http://developer.mozilla.org/presentations/xtech2005/svg-canvas/SVGDemo.xml">the example</a>:
</p>
<pre>&lt;html xmlns="http://www.w3.org/1999/xhtml"&gt;
&lt;head&gt;
  &lt;title&gt;XTech SVG Demo&lt;/title&gt;
  &lt;style&gt;
    stop.begin { stop-color:yellow; }
    stop.end { stop-color:green; }
    body.invalid stop.end { stop-color:red; }
    #err { display:none; }
    body.invalid #err { display:inline; }
  &lt;/style&gt;
  &lt;script&gt;
    function signalError() {
      document.getElementById('body').setAttribute("class", "invalid");
    }
  &lt;/script&gt;
&lt;/head&gt;
&lt;body id="body"
   style="position:absolute; z-index:0; border:1px solid black; left:5%; top:5%; width:90%; height:90%;"&gt;
  &lt;form&gt;
     &lt;fieldset&gt;
       &lt;legend&gt;HTML Form&lt;/legend&gt;
       &lt;p&gt;&lt;label&gt;Enter something:&lt;/label&gt;
          &lt;input type="text"/&gt;
          &lt;span id="err"&gt;Incorrect value!&lt;/span&gt;&lt;/p&gt;
       &lt;p&gt;&lt;button onclick="signalError();"&gt;Activate!&lt;/button&gt;&lt;/p&gt;
     &lt;/fieldset&gt;
  &lt;/form&gt;
  &lt;svg xmlns="http://www.w3.org/2000/svg" version="1.1"
    viewBox="0 0 100 100" preserveAspectRatio="xMidYMid slice"
    style="width:100%; height:100%; position:absolute; top:0; left:0; z-index:-1;"&gt;
    &lt;linearGradient id="gradient"&gt;
      &lt;stop class="begin" offset="0%"/&gt;
      &lt;stop class="end" offset="100%"/&gt;
    &lt;/linearGradient&gt;
    &lt;rect x="0" y="0" width="100" height="100" style="fill:url(#gradient)" /&gt;
    &lt;circle cx="50" cy="50" r="30" style="fill:url(#gradient)" /&gt;
  &lt;/svg&gt;
&lt;/body&gt;
&lt;/html&gt;</pre>
<h3 name="Discussion"> Discussion </h3>
<p>The page is mainly regular XHTML, CSS and JavaScript. The only interesting part is the &lt;svg&gt; element it contains. This element and its children are declared to be in the SVG namespace. The element contains a gradient and two shapes filled with the gradient. The gradient color stops have their colors set by CSS. When the user enters something incorrect into the form, the script sets the <code>invalid</code> attribute on the &lt;body&gt;, and a style rule changes the gradient <code>end-stop</code> color to red. (Another style rule makes an error message appear.)
</p><p>This approach has the following points in its favor:
</p>
<ul><li> We have taken a regular XHTML form that could have been part of an existing Web site, and added an attractive, interactive background
</li><li> The approach is backwards compatible to browsers that do not support SVG; simply, no background appears in them
</li><li> It's very simple and performs very well
</li><li> The picture dynamically sizes itself to the required size in an intelligent way
</li><li> We can have declarative style rules applying to both HTML and SVG
</li><li> The same script manipulates both HTML and SVG
</li><li> The document is entirely standards-based
</li></ul>
<div class="tip">
<p>To add a linked image with DOM methods to an embedded SVG element, one has to use <code>setAttributeNS</code> to set <code>href</code>. Like in the following example:
</p> <pre> var img = document.createElementNS("http://www.w3.org/2000/svg", "image");
 img.setAttributeNS("http://www.w3.org/1999/xlink", "xlink:href", "move.png");  
 </pre>
</div>
<h3 name="Details"> Details </h3>
<p>The <code>viewBox</code> attribute establishes a logical coordinate system which the SVG picture's coordinates are relative to. In this case our picture is laid out in a 100 by 100 viewport.
</p><p>The <code>preserveAspectRatio</code> attribute specifies that the aspect ratio must be preserved by centering the picture in the available size, sizing to the maximum of the height or width and then cutting off any overflow.
</p><p>The <code>style</code> attribute pins the SVG element to the background of the form.
</p>
<h3 name="Related_Links"> Related Links </h3>
<ul><li> Another SVG in XHTML example: <a href="en/SVG/Namespaces_Crash_Course/Example">A swarm of motes</a>
</li><li> <a class="external" href="http://svg-whiz.com/wiki/index.php?title=Inline_SVG">Inline SVG</a> page on SVG wiki
</li><li> <a class="external" href="http://jwatt.org/svg/demos/xhtml-with-inline-svg.xhtml">Working example</a> that works in both Mozilla and in Internet Explorer with Adobe's SVG Viewer installed. (For inline SVG to work in both Firefox and Internet Explorer it is necessary to serve documents with a different Content-Type to each browser. For this reason, if you're behind a proxy server that caches the page, the example wont work in the second browser you load it in because it will receive the wrong Content-Type.)
</li></ul>
{{ languages( { "pl": "pl/SVG_w_XHTML_-_Wprowadzenie", "fr": "fr/Introduction_\u00e0_SVG_dans_HTML", "ja": "ja/SVG_In_HTML_Introduction" } ) }}
Revert to this revision