A List Apart

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

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

by Published in Browsers, HTML, Graphic Design22 Comments

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.

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

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

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

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

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

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

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

22 Reader Comments

Load Comments