Best Practices for Getting Started with SVG

Web graphics in SVG (Scalable Vector Graphics) format offer better quality display over a broader range of device sizes compared to bitmap-based graphics. SVG also has inherent accessibility making it the best choice for interactive graphics and those involving text.

SVG usage on the Web continues to grow. Last week at
SVG Open 2011, we had the opportunity to meet with and hear
from Web developers putting SVG to use in a wide variety of real-world applications.
These applications include data-driving charts, technical drawings, games, interactive
instructional diagrams, and geographic visualization of data.

Though the SVG specification itself is nearing a decade old, SVG wasn’t available
as an inline element in HTML until the HTML5 specification. As browsers support
SVG as part of HTML5, the next generation Web can use these technologies to enable
Web experiences previously available only with the use of plug-in technologies.
SVG’s easy integration with HTML markup, CSS, the HTML DOM, and JavaScript makes
it a natural choice for building integrated, interactive experiences that are stylable
and adaptable to different form factors. SVG is also the declarative vector
graphics technology for building
Windows 8 Metro style apps using HTML.

In this post, I offer ideas for
when to use SVG in your HTML5 Web sites and outline some best practices to help
you get started with SVG.

When to use SVG in HTML5

As the declarative graphics format in HTML5, SVG is designed for
graphics that need to scale, contain selectable text, are dynamic and interactive, or benefit
from being styled using CSS. (For a comparison of SVG and HTML5’s procedural 2D graphics element, <canvas>, see
Thoughts on when to use Canvas and SVG.)

Scalable Graphics

Graphics are used in different contexts and on different mediums. SVG is an excellent choice because fidelity is maintained at all resolutions—important for dealing
with different device form factors and high-quality printing. For instance, SVG
is a great format for logos as illustrated by the W3C HTML5 logo below.

HTML5 logo at different sizes
The W3C HTML5 logo at different sizes

Selectable Text

Images containing text are better served as SVG than a raster alternative. Charts
and diagrams fall under this category. In addition to the added benefit of scalability,
the text in charts and diagrams retains the properties of text. It can be copied
and pasted, searched, and easily updated. Image headers containing decorative text
may be candidates for using SVG. WOFF fonts combined with a text stroke and gradient
or pattern fill enables customized text to remain selectable and indexed by search
engines.

Flow charts, for instance, tend to be composed mostly of text, which incidentally
serves as good search terms for the image. As can be seen in the screenshot below,
the text within an SVG chart can be selected; just like other text, it can be copied,
crawled by a search engine, or even used in conjunction with Accelerators in IE.

SVG flowchart showing selected text
A flowchart showing selected text

Dynamic and Interactive Graphics

Dynamic and interactive graphics can include games, maps, graphs, seating charts,
and more. One use of SVG that Internet users frequently encounter can be found on
Bing and Google maps. When requesting directions, they draw a blue SVG path that
your car should follow, overlaid on a raster map image. SVG can be generated through
client-side scripting, which is great for making minor additions to existing images
as with mapping directions. SVG’s rich DOM support also makes it fantastic
for dynamically changing images. Charts can be updated in the browser as data changes.
Shapes can move and change size or color by altering their DOMs. Additionally, SVG’s
hit testing abilities mean that precise interactions with shapes can occur. Much
like with HTML elements, event handlers can be attached to an SVG element. However,
unlike HTML elements, mouse events will only be affected by mouse interactions on
the shape and not its entire rectangular bounding box.

Map showing SVG driving directions overlay
Map showing driving directions: base map is a bitmap image, driving path is overlaid SVG

Formatting with CSS

The benefits of styling content with CSS are another core reason for using SVG. Every
shape in SVG is reflected in the DOM and contains all information about the graphic,
including the appearance of each shape. This makes it easy to update the styling
information about each shape. UI elements can benefit from using SVG as it allows
for non-rectangular shapes and its appearance is customizable. The fills, strokes,
and opacity of shapes can be modified via a new stylesheet, via script, or even
via a pseudo selector such as :hover.

These benefits of SVG are not mutually exclusive. For example, below is a map graphic
that displays data over time. It scales well and utilizes multiple stylesheets to
show data changes over time. On this map, only the colors of the states are changing. Each state is represented by a <path> element with an id
corresponding to its postal code. Using CSS selectors on these ids, the fill
color of the shapes is specified in stylesheets that are each applied as appropriate
when cycling through years. Election maps often show data trends in this color-coded
manner. You could easily envision live election result updates requiring only minor
modification of the graphic. These updates are simple, isolated, and small.


A choropleth map of the United States illustrating some data over time

Getting Started: Best Practices

Despite SVG’s similarities to HTML, some frequently made errors can easily be avoided.
Listed below are some common mistakes to avoid so that you don’t waste time figuring out what’s going
on.

HTML5 Doctype

If you are including SVG inline in HTML5, make sure you use the
HTML5 doctype <!DOCTYPE html>. This is a requirement of HTML5.
Without specifying the appropriate doctype, your page will not render in the expected
document mode in IE9 or IE10. As a result, your SVG content will not appear. Don’t forget
to specify the HTML5 doctype!

Default Overflow

Like other HTML elements such as <div>, the default overflow for a
top-level inline <svg> element is visible. (This is different from the default behavior of an <svg> element in XHTML, which is “overflow: hidden.”) This default means that SVG content outside
the <svg> element’s bounding box will be visible. In some cases, this can
lead to unexpected behavior. You can remedy this by explicitly setting either the SVG attribute overflow=”hidden”
on your <svg> element or by adding svg { overflow: hidden;
}
to your document’s CSS block.

SVG element with default overflow SVG element with overflow=hidden
<svg>
default overflow is visible
<svg overflow=”hidden”>
SVG content is clipped

Default Text Baseline Position

If you are creating SVG by hand, you may not realize that the y attribute
of <text> and <tspan> elements refers to the baseline of your text.
If you do not specify the y attribute, text is positioned at y=0 relative to its containing transform. This could mean the text baseline is positioned at the top of the SVG container and end up being invisible if you’ve set overflow=”hidden” as described above. So, if you don’t see your text, check to
see if the y attribute is specified with a positive value.

SVG text element default y attribute SVG text positioning with the y attribute specified
<text> (default y=0) <text y=”25″>

Accessibility

Achieving a graphic fully accessible is challenging but because SVG supports adding descriptive text and titles to individual SVG graphic elements and groups of elements, it is possible to create an SVG graphic with much greater accessibility than an HTML <img> element’s alt text.

Without any additional markup, text content is naturally readable by screen readers. For graphic elements, adding <title> and <desc> tags as child elements of
the shape or group allows screen readers access to that descriptive text. Like the title attribute of an HTML <img> element, SVG title elements display as a tooltip with the mouse is hovered over the containing shape.

The following example illustrates the <title> element on a simple drawing.

<?xml
version="1.0" encoding="UTF-8"?>

<svg
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink
="http://www.w3.org/1999/xlink"
width="500" height="300"
viewBox="0 0 500 300">

<title>Abstract Art</title>

<style
type="text/css">

/*<![CDATA[*/

.c0, .c1, .c2 { fill-opacity:
1; fill-rule: evenodd; stroke-dasharray: none; stroke-linecap: round; stroke-linejoin:
round; stroke-miterlimit: 4; stroke-opacity: 1; stroke-width: 10px; }

.c0 { fill: #e3caad; stroke:
#4e320e; }

.c1 { fill: #bc9dc9; stroke:
#4b1268; }

.c2 { fill: #2cec7d; stroke:
#2c9549; stroke-linecap: butt; stroke-linejoin: miter; }

/*]]>*/

</style>

<rect
class="c0" width="131.429"
height="168.571" x="37.143"
y="40.934">

<title>Toast</title>

</rect>

<g>

<title>Bunch of grapes</title>

<path
class="c2" d="M314.286,78.076 340,15.219 428.571,26.648z">

<title>Grape Leaf</title>

</path>

<circle
cx="270" cy="100" r="20" class="c1"
id="grape"/>

<use
xlink:href="#grape" x="40"/>

<use
xlink:href="#grape" x="80"/>

<use
xlink:href="#grape" x="20"
y="35"/>

<use
xlink:href="#grape" x="60"
y="42"/>

<use
xlink:href="#grape" x="38"
y="80"/>

</g>

</svg>

Image fallback of toast and grapes

In addition, the focusable
attribute can be used to enable keyboard access to these descriptions. If focusable=”true”,
a tab stop will be created for that element, making it easy for a keyboard-centric
user to focus on the shape and obtain its information from an accessibility tool.
Additionally, tabbing to and from these elements will trigger the focusin
and focusout events.

MIME type

If you are serving up standalone SVG files, ensure that the server is
configured to be serving up the files with the proper MIME type. The correct SVG
MIME type is image/svg+xml. This is not to be confused with image/svg-xml.
Some already existing content may use the incorrect MIME type due to the Adobe SVG
Viewer’s acceptance of it. Make sure you are using the correct MIME type.

SVGZ files

Similar to the above, if you are using compressed SVG, you should make the line
Content-Encoding: gzip
is in your header response of the SVG file, much like
how other gzip-encoded files should have this header response line.

Scaling: viewBox and preserveAspectRatio

To ensure your graphics will scale the way that you’d like it to, specify the viewBox attribute
on your top-level <svg> element. With a viewBox specified, changing the height
and width of the graphic will scale it rather than clip the SVG image.

The preserveAspectRatio
attribute can also be used to control the scaling of images within SVG. The syntax
of this attribute is preserveAspectRatio=”align meetOrSlice“. These
two parameters describe the how an image is to fit into its containing <image>
element and where the image is positioned within the container. By setting preserveAspectRatio=”none”,
the SVG <image> element behaves like the HTML’s <img> element as illustrated
below.

Photo of two giraffesPhoto of two giraffes scaled to fit odd container
Left: image at its original aspect
ratio; Right: same image stretched into a 200 x 81 container with
preserveAspectRatio=”none”

Things get interesting when preserveAspectRatio is not “none”.
In such cases you control how the image aligns within a container of a different
aspect ratio than the image itself. The meetOrSlice parameter determines
whether the image is scaled down to fit within the container (meet) or scaled
up to fill the container (slice). The align parameter specifies how
to align the image within its container. Three options—min, mid, and max—are
provided for each direction—x and y. This yields nine combinations of alignments
specified as:

  • xMinYMin – align image in left-top corner of container
  • xMidYMin – align image at center-top of container
  • xMaxYMin – align image in right-top corner of container
  • xMinYMid – align image at left-middle of container
  • xMidYMid – align image at center-middle of container
  • xMaxYMid – align image at right-middle of container
  • xMinYMax – align image in left-bottom corner of container
  • xMidYMax – align image at center-bottom of container
  • xMaxYMax – align image in right-bottom corner of container

The following examples show how an image is aligned for its controlling alignment.
Note that align only matters in one dimension at a time; the image exactly fills
the container in the other dimension so it doesn’t matter whether that dimension is min, mid, or max.

xMin Example of preserveAspectRatio="xMinY* meet"
xMid Example of preserveAspectRatio="xMidY* meet"
xMax Example of preserveAspectRatio="xMaxY* meet"

YMin YMid YMax
Example of preserveAspectRatio="x*YMin meet" Example of preserveAspectRatio="x*YMid meet" Example of preserveAspectRatio="x*YMax meet"

meetOrSlice parameter = “meet”:
image is scaled down to fully fit within the container leaving empty space if the
container aspect ratio differs from that of the image

xMin xMid xMax
Example of preserveAspectRatio="xMinY* slice" Example of preserveAspectRatio="xMidY* slice" Example of preserveAspectRatio="xMaxY* slice"

YMin Example of preserveAspectRatio="x*YMin slice"
YMid Example of preserveAspectRatio="x*YMid slice"
YMax Example of preserveAspectRatio="x*YMax slice"

meetOrSlice parameter = “slice”:
image is scaled up to fully fill the container cuttin off some of the image if the
container aspect ratio differs from that of the image

SVG’s preserveAspectRatio property gives you the control to define both the scaling and positioning
of an image within its container. preserveAspectRatio=”none” yields behavior common with HTML.

Scripting: SVG DOM vs. Core DOM

The getAttribute() and setAttribute() methods come from the DOM Core specification
and apply to HTML and XML alike, including SVG. These methods are familiar, easy,
and consistent ways to make changes to element attributes. Regardless of the attribute
to be changed, setAttribute(attribute, value) can always be used.
However, performance gains can often be attained by taking advantage of the SVG
DOM. SVG supports its own DOM that exposes a multitude of attribute values and methods.
Due to the nature of the SVG DOM, modifying attribute values requires a steeper
learning curve than simply using setAttribute(). But the SVG DOM provides direct
access to attribute values, which both improves performance and can make value manipulation
simpler.

For instance, the following function doubles the radius of a circle element using
setAttribute():

function doubleCircleRadius(circle)
{

circle.setAttribute("r",
2 * parseFloat(circle.getAttribute("r")));

}

By contrast, using the SVG DOM, achieving the same effect looks like this:

function doubleCircleRadius(circle)
{

circle.r.baseVal.value *= 2;

}

With the setAttribute() and getAttribute() methods of the Core DOM, parsing will
often be required to manipulate values. Modifying values based on the existing ones
is easier done with the SVG DOM.

Because the SVG DOM accesses attributes directly instead of dealing in strings, value
type awareness is necessary and makes scripting with it more complex.

Below is a table describing a generalization of how to access a few common attributes:

Value “type” Attribute examples DOM access
Presentation attribute fill, stroke elem.style.fill
Length r, width, height, cx, cy, x, y elem.r.baseVal.value
Object viewBox elem.viewBox.baseVal.x
elem.viewBox.baseVal.y
elem.viewBox.baseVal.width
elem.viewBox.baseVal.height
List transform, d elem.transform.baseVal.getItem(0);

The SVG DOM interfaces are documented at the
end of each chapter in the SVG specification.

Tools & Libraries

Though SVG is readable and can be crafted by hand, it is still largely visual and
often unintuitive to translate a visual graphic into a mathematical description
of its shape. Using vector design tools already in existence today, static SVG images
can easily be created. Inkscape is an option
available for free download.
Adobe Illustrator, often used by professional Web developers to create vector
images, can save files in the SVG format.
Microsoft Visio, also capable of exporting in an SVG format, is tailored
towards developing business diagrams and flowcharts. If optimization is important
to you, note that these applications do not output SVG in the simplest format;
their output contains proprietary namespace elements and attributes that allow for round-trip editing but are not useful for final production
graphics. Additional markup cleanup may be desired for a reduction in file size
or for easy styling.

In addition to Inkscape, another free SVG editor is
SVG-edit. It is a JavaScript SVG editor and uses your browser to render the
SVG creation! The
latest alpha version has some great features. Try it in IE9!

IE9 supports WOFF fonts instead of SVG Fonts. WOFF
fonts bridge the gap between HTML and SVG, reducing the learning curve
for SVG and integrating SVG as a part of HTML. This makes it easy to apply the
same custom fonts to both your HTML and SVG content. For those already acquainted
with SVG fonts, Font Squirrel
can convert your SVG Fonts to the WOFF format.

Another common problem is providing fallback support for older versions of IE that
do not support SVG. SVG libraries on the Web often provide fallback support and
abstract the process away from you. RaphaelJS
is one of the most widely known that displays VML in older versions of IE. Charting
libraries that provide graceful fallback, such as
Highcharts are springing up all over the web.

These are just a few basic resources to help you get started. The tools and
libraries in existence today fall into two camps: (1) creation of
static, standalone SVG content and (2) programming dynamic, script-driven, and script-created
SVG. Both have their place in your toolbox. For those of you pioneering SVG on the Web, you’ll
find there is a lot to play around with.

Call to Action

You’ve
seen
SVG
in use.
With its benefits outlined and some practical tips to avoid early roadblocks, there’s
every reason to start experimenting with SVG to see how you can take advantage of
it on your HTML5 Web site. Post some of your creations or links to other libraries – we’d love to see them!

—Jennifer Yu, Program Manager, Internet Explorer Graphics


IEBlog