Using SVG for Flexible, Scalable, and Fun Backgrounds Part II
Issue № 299

Using SVG for Flexible, Scalable, and Fun Backgrounds, Part II

In Part I, I talked about browser support, when you can use SVG (and when you shouldn’t), and accessibility. In this article, I’m going to dig into the technology behind using SVG for your site design. We’ll explore how to incorporate SVG in a cross-browser friendly manner, including using SVGWeb to ensure that the SVG shows in Internet Explorer. I’m also going to cover the truly unique characteristic that makes SVG ideal for page backgrounds: scalability.

Article Continues Below

Of course, to use SVG you must have SVG. In this article, I’ll introduce you to Inkscape, a free, open source tool that does a marvelous job of converting bitmaps to SVG. I’ll also cover the many places to discover SVG online that you can freely use.

Adding SVG to your Web Page#section2

There are multiple ways to add SVG to a web page, though only a few are cross-browser compatible.

The first method is to use the object element and reference an external SVG file. This approach is currently the most popular way to add SVG to a page served up as HTML.

To add SVG using the object element, write markup such as the following, which I copied from Jeff Schiller’s site (mentioned in Part I):

  <object type="image/svg+xml" 
    width="100" height="100" style="float:right" 
    data="http://blog.codedread.com/clipart/apple.svgz">
  <span/></object>

Set the type to the SVG MIME type “image/svg+xml.” Supply the width and the height (you can use a stylesheet), and set the src attribute to the SVG file. In this example, Jeff uses the gzipped version of SVG, to save that much more bandwidth (more on creating SVG files, later). To see the example graphic, open the SVG file in Firefox, Opera, Safari, or Chrome. Example 1 shows the SVG added to a web page via the object element.

Currently, using the object element is the only native approach that works with HTML. As support for HTML5 increases, more browsers will support SVG embedded directly into HTML. Another advantage with this approach is that you can use existing SVG files and don’t have to touch the XML.

However, one disadvantage to using the object element is that stretching the object element to cover an entire page can be problematic, depending on the browser. For example, Safari/Webkit does not currently render a transparent background for the object element.

The disadvantages to using object lead us to a second way to incorporate SVG into a page design: CSS. With CSS, you can use an SVG file in place of a JPEG or PNG in your background-image settings:

body {
 background-image: url(redcircle.svg);
}

Example 2 demonstrates the CSS approach to adding SVG as a background element. This is a good option, except that currently, Firefox does not support SVG in CSS. Until it does, it’s not a really viable option. You can also use SVG in image elements, but this has even less support than SVG in CSS.

The last approach to adding SVG to a web page is the one I use the most. Simply embed the SVG directly into the web page using the SVG element. You can do this in two ways: You can serve your web pages up as application/xhtml+xml, which works with Chrome, Firefox, Safari, Opera, and various other browsers (but not IE), as shown in Example 3. Or, you can embed the SVG element into HTML, serving the page up as HTML, which is allowed in HTML5, as shown in Example 4. Note, though, that SVG embedded in HTML only works with Firefox 3.6 at the time of this writing. Also note that the HTML5 validator generates an error when you embed SVG in HTML5—not because the SVG is an error, but because only one browser currently supports this new functionality.

Embedding the SVG into XHTML is as simple as copying and pasting an SVG element from a file. Typically a file may have a beginning, such as the following:

  <?xml version="1.0" encoding="UTF-8" ?>
  <svg viewBox="0 0 400 253" 
   version="1.1" xmlns="http://www.w3.org/2000/svg" 
   preserveAspectRatio="none">

Or:

  <?xml version="1.0" encoding="UTF-8" standalone="no"?>
  <!-- Created with Inkscape (http://www.inkscape.org/) -->
  <svg   xmlns:svg="http://www.w3.org/2000/svg"
    xmlns="http://www.w3.org/2000/svg"
    xmlns:xlink="http://www.w3.org/1999/xlink"
    xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"   
    version="1.0"   
    viewBox = "0 0 725 828"   
    preserveAspectRatio="none"   
    id="svg2">

The part that you want to copy is the file contents between the opening and closing SVG tags, including the tags themselves. Make sure you don’t forget the closing SVG tag.

You can paste the SVG wherever you want in the page, but I recommend pasting it into a div element toward the bottom of the page, as shown in Example 3. You can position it as a background image using CSS, and make sure it’s behind all the other page elements using the z-index property.

You’ll use the same procedure to embed SVG into an HTML document. However, as mentioned earlier, the only browser that supports SVG in HTML at this time is Firefox 3.6. If you’re going to embed the SVG into HTML, I recommend that you use a library, such as SVGWeb. Not only can you embed SVG into HTML with SVGWeb, but the result should also display in IE, as long as the Flash plug-in is installed.

Using SVGWeb#section3

Using SVGWeb is very simple—simply download the zipped file, which includes the demos and source, and add the JavaScript library to the page. Just make sure it’s located before any other JavaScript library:

<script src="src/svg.js" data-path="src/"></script>

SVGWeb consists of several libraries, so you’ll either need to ensure that the other libraries are in the same path as the primary svg.js library, or you’ll need to provide the HTML5 custom data attribute, data-path. In addition, make sure you upload all the SVGWeb src directory contents to where SVGWeb will be used on your website.

Once you’ve uploaded the SVGWeb libraries, and added the script tag, embed the SVG, as you would using XHTML. It’s important to surround the SVG tag with a script element:

  <script type="image/svg+xml">        
    <svg ...>...</svg>
  </script>

If the page is served up as XHTML, include a CDATA setting:

  <script type="image/svg+xml"><![CDATA[
    <svg ...>...</svg>
  ]]></script>

Using SVGWeb not only ensures that the SVG displays in HTML, but also that it displays in IE. You add the library and the surrounding script tag, and SVGWeb takes care of the rest. It loads the SVG/XML, makes it accessible to scripting, and ensures that the SVG displays regardless of the browser. There is a small premium, though. The SVGWeb library, like most of the cross-browser SVG libraries, requires JavaScript to be turned on. In addition, the SVGWeb library increases bandwidth use, and when IE is used to access the page, further additional bandwidth is required for the Flash component of the library.

I’m demonstrating using SVGWeb with inline SVG, but SVGWeb also works with the object element.

Regardless of whether you use an object element or embed the SVG directly, if you want the image to scale to the contents of the page, you must use absolute positioning for the SVG or object. If you want the SVG to scale to the size of the whole page, even if the page contents extend beyond the browser viewpoint, add the SVG to an outer container that also holds the page contents. Make sure the page contents, and the other container, are positioned relatively, to ensure that the SVG sizes correctly. The examples just listed demonstrate both techniques: Example 3 scales to fit the whole page. Example 4 scales only to the browser window.

About that scalability thing#section4

Earlier, we demonstrated how to open the SVG listed in the object element example directly in your browser. Notice that the graphic is much larger than it would appear as an icon in Jeff’s page. That’s because of two things—the SVG attribute viewBox, and the size of the container in which the graphic is opened.

Jeff’s SVG element has a viewBox attribute equivalent to the graphic document size:

	viewBox="0 0 740 850"

The viewBox attribute ensures that the graphic bounded by the box specified in the viewBox setting stretches to fit the container. The attribute is given one value, the bounding box dimensions, beginning with the x y pair, and then the width and height—x is first, y is second, width is third, and height is the fourth value. When Jeff opened the SVG in an object element with a given height and width, the graphic appeared to be that size. When opened in a browser window, the graphic appears to be that much larger.

Another SVG attribute defines how the graphic scales: preserveAspectRatio. Jeff’s SVG doesn’t specifically set this attribute, so the SVG’s preserveAspectRatio is set to the default, which is to scale proportionately. You can see this in action with the Emacs in Mac OS X web site. With this site, if you resize the browser window vertically, the image scales both vertically and horizontally, to ensure that the graphic looks proportional. Ditto for resizing the window horizontally, or in both directions.

However, if you open Frugal Algorithm and resize the browser window, you’ll see that the graphic can distort, shrinking horizontally, if the window is scaled horizontally (Figure 3), or vertically (Figure 4), or both. I set the value of preserveAspectRatio to ”none,” because I want my graphic to fill the space it’s given, regardless of the size of space. I’m not attempting to preserve the aspect ratio.

Frugal Algorithm site displayed in narrow window
Fig 3. Frugal Algorithm site displayed in narrow window
Frugal Algorithm site displayed in wide window
Fig 4. Frugal Algorithm site displayed in wide window

The latter approach can be an effective way to provide a background image for a web page, but can be challenging to use. For instance, I’ve learned that a graphic with a width five times the height makes a bottom border image that looks good regardless of the browser size. I also set the SVG element to be fixed, positionally, so that it’s always displayed.

A background image that fits the entire web page can be more challenging. I’ve learned that a simple graphic with a strong diagonal feel, sized to fit 100% of the page’s height and width, can be a fun and effective background graphic that seems to be a custom fit to the web page size, as shown in Figure 5, and also demonstrated in Example 5.

SVG Feed site with paintbrush background image
Fig 5. SVG Feed site with paintbrush background image

To return to Jeff’s use of SVG, he uses one SVG background element to provide a blue border that surrounds the content on his site. Look at the SVG in the page, though, and you’ll see that he’s using multiple SVG elements to create the effect. The vertical line is hard coded to a 100 pixel width that can stretch 100%; the horizontal has a 100 pixel height that can stretch 100%. The rounded corners are actually a gradient, defined elsewhere:

  <svg id="leftedge" version="1.1" width="100%" 
   height="100%" 
   xmlns="http://www.w3.org/2000/svg">    
   <rect width="100px" height="100%" 
    fill="url(#leftgrad)" />  
  </svg>
  <svg id="rightedge" version="1.1" width="100%" 
    height="100%"
    xmlns="http://www.w3.org/2000/svg">    
   <rect width="100px" height="100%" 
    fill="url(#rightgrad)" />  </svg>
  <svg id="header" version="1.1" 
   xmlns="http://www.w3.org/2000/svg">
   <rect width="100%" height="100px" fill="url(#topgrad)" />
   <rect width="100px" height="100px" 
    fill="url(#gradcornerTL)" />
   <rect x="100%" width="100px" height="100px" 
    fill="url(#gradcornerTR)"
    transform="translate(-100,0)" />  </svg>
 

Note that the gradient used to fill the rectangles is defined elsewhere. This is another interesting aspect of SVG within a web page: You can define patterns and gradients in one place and use them in many different places. I used this approach with my old photo picker gradient, to fill the capstones around the comments with a gradient based on the photo colors.

The SVG 1.1 specification covers additional options you can use to manage your SVG image’s aspect ratio.

Creating SVG#section5

You can find SVG ready to use on the web, and I’ll get into good sources for SVG later in this section. However, you can easily create your own SVG, either using a tool you already have, such as Adobe Illustrator, or using a tool such as Inkscape, which is a freely available, popular, open source vector graphics tool. Figure 6 shows Inkscape opened, with a bitmap that’s being readied to convert to SVG.
Another SVG editor is SVG-edit, which is also freely available, and based in JavaScript. And because it is JavaScript-based, you can embed the tool in any web page, providing SVG editing capability to others. If you don’t want to install a tool, or embed a tool in a web page, you can also use the vector editor Raven, at the Aviary web site.

Inkscape with bitmap clip art
Fig 6. Inkscape with bitmap clip art

If you already have a simple JPEG or other bitmap graphic, you can convert the bitmap to SVG. Depending on how much of the graphic you want to capture, you could end up with something that’s actually superior to the original, or at least, an interesting version of the original.

One tool you can use to convert bitmaps to SVG is Vector Magic, which comes in both an online and a desktop version. Vector Magic provides various options to control the output, and does an excellent job, particularly with more complex images. You can try Vector Magic without subscribing to see the transformational effect for yourself. WP Clipart has several freely available images that vectorize well.

You can also use Inkscape to easily convert bitmaps into SVG, as demonstrated in the following steps:

  1. Open the image in Inkscape.
  2. Once opened, select the image by clicking on the Edit menu, and then Select All.
  3. Select the Path menu, then select Trace Bitmap. This opens the bitmap trace dialog, as shown in Figure 7.
  4. You’ll most likely want to use Multiple Scans, and the Colors option. You can leave the number of scans at eight to start. Accept the Smooth and Stack Scan options. If you want to remove the background color, select the Remove background option.
  5. Click on the update button to convert the bitmap to a vector, as reflected in the preview window, shown in Figure 8.
  6. If you like the result, click the OK button. Otherwise, tweak the settings until you get the result you want.
  7. Close the dialog to return to the editor.
  8. You’ll want to delete the original bitmap. Select the layer that contains the bitmap, select Edit and then Delete. What’s left is your converted vector, as shown in Figure 9.
  9. At this point, you can select paths or pieces of the SVG to alter, remove, or add new pieces.
  10. Once you’re satisfied with your graphic, export it as SVG. Select the File menu, and then Save As. In the dialog that opens, make sure you pick the Plain SVG option in the lower right. Tip: saving in Inkscape format adds a whole lot of markup to the image that you don’t typically need if you’re going to be using the image directly on the web.
Opening the Trace bitmap dialog window
Fig 7. Opening the Trace bitmap dialog window
Trace bitmap dialog window
Fig 8. Trace bitmap dialog window

To see for yourself how well Inkscape converts bitmaps, I created the following SVG images using public domain clip art I found on the web: public domain logo (JPEG, SVG), coffee mug (PNG, SVG), spring flowers (PNG, SVG), coloring pencils (PNG, SVG), and Halloween symbol (PNG, SVG). The latter two required more paths until I was satisfied with the image. Typically, the more complex the image, the more paths you’ll need to capture all the color variations in the image.

Once you have your SVG, your drawings can be static, or you can use JavaScript to animate any aspect of the SVG. You can even use the declarative animation techniques built into SVG, though you may want to save the animation for charts, rather than page design.

Using Found Vector Graphics in your Designs#section6

The web is rich with vector graphics in other formats, such as EPS or Adobe Illustrator (.ai). Like SVG, many of the vector graphic files are free to use, at least for personal websites. If the format isn’t already an SVG, a quick Google search turns up several techniques and resources you can use to convert the format to SVG. Inkscape also maintains a a list of conversion tools. Additionally, Adobe Illustrator can also export vector graphics as SVG.

The Open Source Clip Art Library is a great place to discover existing SVG and many different kinds of public domain graphics. Once you have the graphic file, you can modify it to fit your needs, or combine several graphics into one. If you’re new to SVG, use Inkscape to modify the image, otherwise, you may be able to tweak the SVG directly, using an XML editor. A Google search for “vector silhouettes” turned up many of the source files for the silhouettes on my sites.

Optimizing and Enhancing SVG#section7

To ensure that the SVG is optimized for web use, run the utility Scour on it to eliminate inefficiencies and extraneous whitespace after you’ve copied, converted, and tweaked your SVG file. Scour is a simple Python script Jeff Schiller created. It can run from the command line, or as an Inkscape extension.

The important thing to remember when creating or searching for SVG to use in your web design, is that you don’t have to worry about size: An image in SVG looks good, whether it’s tiny or huge. Also, you don’t have to worry about whether the image is exactly what you want, either, as SVG is extremely malleable. It’s this combined scalability and malleability that makes SVG a new, and fun, web design tool.

To demonstrate what you can do with existing SVG, let’s visit the EMACS for OS X site one more time. This time, instead of focusing on the forefront image, I’ll access the SVG that provides the gradient background. I separated this SVG out into a file:


 <svg xmlns="http://www.w3.org/2000/svg" version="1.1"
  preserveAspectRatio="none" viewBox="0 0 100 100"
  style="width:100%; height:100%; position:fixed; top:0;
  left:0; z-index:1">
  <linearGradient id="background_gradient_black" 
   x1="0%" y1="10" x2="0%" y2="90" 
   gradientUnits="userSpaceOnUse">
  <stop offset="0%"   stop-color="#000" 
   stop-opacity="1" />
  <stop offset="45%"  stop-color="#444" 
   stop-opacity="1" />
  <stop offset="55%"  stop-color="#444" 
   stop-opacity="1" />
  <stop offset="100%" stop-color="#000" 
   stop-opacity="1" />
  </linearGradient>      
  <rect x="0" y="0" width="100" height="100" 
   fill="url(#background_gradient_black)" />
 </svg>

This SVG uses a gradient. Gradients are implemented in stops, where each “stop” specifies the offset where the gradient stop is completely finished. The engine implementing the image ensures that the color from one stop gradually blends into the color from the next stop.

I like the gradient, but I’d like a little more color. For instance, I’d like the gradient to incorporate a little yellow, and a little red, and adjust the stops accordingly:

<svg xmlns="http://www.w3.org/2000/svg" version="1.1"
 preserveAspectRatio="none" viewBox="0 0 100 100"
 style="width:100%; height:100%; position:fixed; top:0; 
 left:0; z-index:1">
 <linearGradient id="background_gradient_black"
  x1="0%" y1="10" x2="0%" y2="90" 
  gradientUnits="userSpaceOnUse">
 <stop offset="0%"   stop-color="#000" stop-opacity="1" />
 <stop offset="35%"  stop-color="#200" stop-opacity="1" />
 <stop offset="65%"  stop-color="#600" stop-opacity="1" />
 <stop offset="100%" stop-color="#ff0" stop-opacity="1" />
 </linearGradient>    
 <rect x="0" y="0" width="100" height="100" 
  fill="url(#background_gradient_black)" />
</svg>

Lastly, I grabbed the silhouette SVG I use for my Frugal Algorithm site, and added it the same web page as my newly modified background gradient, as shown in Figure 9. Because SVG is vector-based, merging many images and modifying the result is extremely simple—much more so than with bitmaps.

Combing SVG background images
Fig 9. Combing SVG background images

Being able to easily combine multiple vector graphics, and modify the result is just one fun aspect of SVG. As we’ve seen in this article, SVG can also be cross-browser friendly, and relatively simple to create.

It is SVG’s scalability, though, that adds a new dimension to our site designs. No longer are we constrained to fixed widths and heights in an environment that is flexibly sized.

About the Author

Shelley Powers

Shelley Powers is a member of the W3C HTML Working Group, and a web developer and system architect with 25 years of experience. She’s also a writer and has authored and co-authored over 17 books, including Painting the Web, Adding Ajax, Learning JavaScript 2nd edition, Practical RDF, and the upcoming The JavaScript Cookbook, all published by O’Reilly. Shelley has a set of web sites, all accessible from the main site, Burningbird, at http://burningbird.net.

22 Reader Comments

  1. Hey Shelley, cool article, but is that supposed to be in the first code sample above?

    I totally love that people are using this, but with all the limitations still, I honestly don’t see myself diving in too deeply just yet…

    But thanks, I love to see new uses, and hope someday this will finally come of age…
    Atg

  2. I also can’t see anything but text in Firefox 3.6. Example 3, on the other hand, displays just fine.

  3. I just a novice on SVG.
    I would like to know if SVG can replace Flash as used in the web (other than video and audio –handled by HTML5 tags–).
    I suppose that JavaScript can handle dynamics.
    Is there any other way of doing animations than “hand coding”?
    Is there any application that let “non-programing artist” work easyly with SVG?

  4. Thanks for kind words, folks.

    The example 4 is a demonstration of using SVG in HTML via the HTML5 spec. The only browser that supports this currently is Firefox 3.6. And unfortunately, we’re now finding out Firefox 3.6 only seems to support it in the Mac.

    SVG-in-HTML5 support is enabled by default, and it is showing in my Mac Firefox 3.6, but just checked with an updated Windows version, and it isn’t. Well, isn’t this fun? Which just goes to show that SVG-in-HTML is still very new, very raw, and you might want to stick with either SVG-in-XHTML, or use the scripting libraries such as SVGWeb to incorporate in HTML. It will be a few years before we see widespread support for SVG in HTML.

    Aaron, yes, that object code is copied as is directly from Jeff’s site. The span would normally enclose fallback text.

    Imasanti, several applications support SVG, including Inkscape and Adobe Illustrator. I don’t think there’s a Flash-like equivalent for SVG, yet. I know folks were looking at creating one of these a year or so ago.

  5. Example four doesn’t work for me either. Is Snow Leopard the problem perhaps?

    Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; en-US; rv:1.9.2) Gecko/20100115 Firefox/3.6

  6. Folks, my apologies:

    I did not include in the article directions for enabling HTML5 in Firefox 3.6. I did this so long ago, that I forgot.

    You have to enable HTML5 support before the SVG will show. The only way to enable support for HTML5 is by typing the following into the location bar:

    about:config

    In the page that opens, after the warning, you then look for a property:

    html5.enable

    You need to set this to true.

    This is only for folks that are comfortable with this bleeding edge change.

    In the meantime, I have an XHTML version that you can all see at

    http://burningbird.net/svg/example4.html

  7. I think when HTML5 becomes the norm, we will see a lot more of SVG on the web. That is why I added a bunch of support for SVG in the 1.5 release of Firebug. It’s fun to tinker like that!

  8. Shelley already mentioned that she had forgotten she had flipped the html5.enable pref to true.

    Since I implemented the preference in Firefox, I thought I’d clarify a few of things:
    # Firefox 3.6, as shipped in its default configuration, does _not_ support SVG in text/html.
    # There is no Mac vs. other difference here. The hidden pref is cross-platform.
    # The pref does more than enables SVG in text/html. Flipping the pref replaces the entire HTML parser in Gecko with a snapshot of an HTML5 parser as of end of June 2009. If you use the old snapshot of the parser, you’ll be exposed to bugs that have been fixed since the end of June. Thus, if you want to be on the edge and use an HTML5 parser, it’s much better to do so with “trunk nightlies”:http://nightly.mozilla.org/ than with the 3.6 release.

  9. I was wondering about all that SVG stuff, had no idea about it.There is a lot to learn for me, this will be my starting point.

    Thank you for this great article!

  10. Embedding SVGs into websites is something that concerns me. It’s not because I don’t trust your word or not believe what you’re saying — I do. I just don’t feel comfortable using a filetype that takes so much work for such minor results.

    However, I’m going to keep this article in mind and look for a situation where I can use SVG images in the future. But it’s doubtful that it’ll be applicable to the type of sites I design.

    Either way, thank you for taking the time to write up this two-part article.

    Regards,
    Luke

  11. Hi Shelley! 🙂

    Great article(s)! Few nits:

    bq. For example, Safari/Webkit does not currently render a transparent background for the object element.

    FWIW(For What It’s Worth), that’s “bug 10687”:https://bugs.webkit.org/show_bug.cgi?id=10687. If one’s interested, just CC to that issue, as the WebKit bug tracker doesn’t allow voting. 😉

    Also, at first I didn’t understand the empty span element when embedding SVG within an object tag. That will be used as fallback content, so it is useful whenever SVG is *only* for decoration. When it’s used for functionality, then one *will* definitely want to display fallback content. 🙂 Details in a “related SVG Developers thread”:http://tech.groups.yahoo.com/group/svg-developers/message/60373… 😉

  12. Hi Shelley,

    first off thanks for these articles. Nice read.

    As pointed out in the 2nd comment, the -tag (with funny ending slash?) should be removed because as you can see, it’s confusing. 😉 And some people might even copy and paste it as is.

    Another little mistake from the same paragraph: you tell readers to “set the src attribute to the SVG file”. This should be the “data attribute”, of course, as seen in the example you provide.

  13. Hi,

    I’m currently working on a project for a client and i’m using a resizable background image. I want the website to look fresh on every load so want two use the rotator.php for this.

    Anyone knows what is the best solution to make a website where background img height and with always is 100%, resizes when you scale the brower and renews the image on every load?

    Thanks,

    Janis Sevens

  14. would love to see web page and code examples of how svg can be positioned and scaled in place of gif and jpg graphics (not just backgrounds )and how to give the user zoom control of the graphic that could scale (top z index) over the rest of the page.
    thanks

Got something to say?

We have turned off comments, but you can see what folks had to say before we did so.

More from ALA