Adobe

decor

Web Platform Team Blog

Making the web awesome

SVG Styling

SVG is the standard scalable vector based graphics format for the web and it’s supported by all modern web browsers. SVG’s importance has grown with the increasing number of high resolution devices. JavaScript libraries like Raphaël can be used as shims to support Internet Explorer 6 – 8. The more people update to modern browsers, the less authors need to care about support for older browsers. Let’s look at the era after Raphaël. Let’s start to look at some of SVGs strengths — like styling.

Responsive web design

Responsive web design is not just about layout for different screen sizes or resolutions. Design is about moods. Integration with the color scheme of a web page is at least as important as the layout of it. The following example from Vincent Hardy demonstrates how flexible SVG really is.

The example consists of an HTML document with the embedded graphic “svgwow.” As you click the links at the top, the design of the document changes and the SVG graphic changes along with it. The impressive part: The SVG graphic stays the same all the time! No markup changes or redrawings with JavaScript are involved. The graphic always adapts to the current design of the web page.

Stylesheets for SVG

SVG was designed to be customized with stylesheets. Since SVG is based on XML, there are at least two possible stylesheet languages: XSL and CSS. The usage of CSS is very similar to how it is used in HTML.

External Stylesheets

Like in HTML, there are different ways to set the style. External stylesheets are one way. Since SVG is an XML document, external stylesheets are referenced as follows:

<?xml-stylesheet type="text/css" href="stylesheet.css" ?>
<svg xmlns="http://www.w3.org/2000/svg">

Document Stylesheets

Document stylesheets (styles defined in the document itself) can be set with the <style> element:

<style type="text/css" >
  <![CDATA[
    ...
  ]]>
</style>

It is possible to use classes and references by id as well. Each SVG element has support for the class and id attributes. CSS selectors are supported as well.

<style type="text/css">
  <![CDATA[
    .dots { fill: blue; }
    .dots:hover { fill: yellow; }
    #middle { stroke-width: 5px; stroke: black; }
  ]]>
</style>
<circle cx="100" cy="100" r="75" class="dots" />
<circle cx="200" cy="100" r="75" class="dots" id="middle" />
<circle cx="300" cy="100" r="75" class="dots" />

To see this in action, hover over the blue circles below.

Inline style

Inline stylesheets can be set with the style attribute.

<circle cx="100" cy="100" r="75" style="fill: blue;" />

Presentation attributes

Presentation attributes are special style properties. It is possible to set them in a stylesheet,

<style type="text/css" >
  <![CDATA[
    circle { fill: blue; }
  ]]>
</style>
<circle cx="100" cy="100" r="75" />

in the style attribute,

<circle cx="100" cy="100" r="75" style="fill: blue;" />

or as standalone attribute.

<circle cx="100" cy="100" r="75" fill="blue" />

You may ask why SVG has attributes for style properties (e.g. fill="blue"). SVG 1.1 did not require CSS. Therefore, it was necessary to describe the style with only attributes as well. See the list of presentation attributes in the SVG specificationn.

It is helpful to know that the attributes contribute to the cascading of CSS. Presentation attributes count as low level “author stylesheets” and are overridden by any other style definition from the author (external stylesheets, document stylesheets and inline styles). Therefore, the circle in the following example will be blue.

<circle cx="100" cy="100" r="75" fill="red" style="fill: blue;" />

The graphic below illustrates the model of the cascade.

Cascading of presentation attributes

Styles lower in the diagram override those above them.

Can I continue to use JavaScript libraries?

I mentioned the era after the library Raphaël in this article’s introduction. You may ask if you can still use JavaScript libraries? Definitely! Raphaël is a shim, limited to the subset of features supported by all platforms (with the main limitation being Internet Explorer 6-8). D3.js and BonsaiJS are examples of libraries that extensively use SVG’s features. Libraries will continue to make progress and take more capabilities of SVG into account. Styling support is one of these capabilities that will be better supported by libraries in the near future.

The future of styling in SVG

The SVG working group (responsible for specifying SVG), is looking for a better integration of CSS with SVG. More SVG attributes will turn into presentation attributes, CSS Animations and CSS Transitions will be supported soon, CSS Images will be integrated to allow the use of CSS gradients and much more. The group is always interested in new proposals that excite the web community. Contribute your suggestions to the SVG mailing list!

4 Comments

  1. January 09, 2013 at 12:33 am, Tobias Reiss said:

    Awesome, great blog post dschulze!

    The paragraph about “Presentation attributes” is a little bit confusing to me, though. Sounds like one could specify a presentation attribute in three ways (inline, stylesheet, standalone). I think it’s the other way round. A style property (“fill”) can be specified in different ways (as mentioned in your blog). One is via its XML representation, which is a XML attribute, also called “presentation attribute” (what you describe as “standalone”). Maybe I’m wrong but that would also make the graphic about the “model of the cascade” more clear to me. Please correct me if I’m wrong :)

    • January 11, 2013 at 6:36 am, dschulze said:

      No, you are right. After all a “Presentation attributes” is a CSS property that can be set in one more way then other CSS properties: with an attribute. (Not sure if we still can name it XML attribute in times of HTML5 with SVG support :).)

  2. January 25, 2013 at 2:38 am, Prad said:

    Hello,
    Is there’s a way to make a long curved line appear slowly (like if you were drawing it) in SVG ?
    The idea is to import it in Edge Animate.

    THX
    françois

    • February 04, 2013 at 3:53 pm, dschulze said:

      Hi François,

      There are different approaches to make this possible on WebKit browsers, Firefox and Opera. You need to know the length of the path first.. The approach is to create a dash array for this path. with a gap of the length of the path and a visible path of the length of the path. Then you animate the dash array offset of this path. This animation is done with the ‘animate’ element.

      Some JS libraries provide this kind of animation as well. Dmitry wrote a short example how you can do this with RaphaelJS: http://jsfiddle.net/PPjhZ/