Adobe

decor

Web Platform Team Blog

Making the web awesome

CSS & SVG

With the addition of CSS transitions and transforms, web developers can create interactive content with relatively simple markup. Understanding how to use these features with SVG, which has its own transform and animation systems, can be a little difficult.

For example, let’s take a look at a simple interactive element, which animates its color and rotation when moused over.

Note: The demos use features still under development. They should display fine in the latest versions of Safari, Firefox, Chrome, and Opera, but you may see some issues with IE9.

<svg xmlns="http://www.w3.org/2000/svg">
    <rect x="50" y="50" width="100" height="100" 
     rx="20" ry="20" fill="blue">
        <animate attributeName="fill" to="green" 
         begin="mouseover" dur="0.5s" fill="freeze" />
        <animate attributeName="fill" to="blue" 
         begin="mouseout" dur="0.5s" fill="freeze" />
        <animateTransform attributeName="transform" 
         type="rotate" from="0 100 100" to="30 100 100" 
         begin="mouseover" end="mouseout" dur="0.5s" 
         fill="freeze"/>
        <animateTransform attributeName="transform" 
         type="rotate" from="30 100 100" to="0 100 100" 
         begin="mouseout" end="mouseover" dur="0.5s" 
         fill="freeze"/>
    </rect>
</svg>

The SVG markup involves four declarative animations, one for the mouseover fill animation to green, one for the mouseover rotation to 30 degrees about the point 100, 100, one for the mouseout fill animation to blue, and one for the mouseout rotation to 0 degrees about the point 100, 100. This type of SVG animation (SMIL) offers a large degree of customization, but in exchange the markup can become quite dense, especially in the case of a simple state animation.

CSS transitions and transforms give us another method of specifying the same animation. We can generate a similar effect using two styled divs.

#csscontainer {
    position: relative;
    width: 200px;
    height: 200px;
}
#cssrect {
    position: absolute;
    left: 50px;
    top: 50px;
    width: 100px;
    height: 100px;
    background-color: blue;
    border-radius: 20px;
    transition: all .5s ease-in-out;
}
#cssrect:hover {
    background-color: green;
    transform: rotate(30deg);
}
<div id="csscontainer">
    <div id="cssrect"></div>
</div>

In this example, the inner “rect” div has two different styled states, normal and hovered. The states differ only in background color and transform. Using the CSS transition property, we can tell browsers to animate between the two.

Can we use the same CSS styling in SVG? Well, almost. SVG already has some existing support for CSS. If we were to draft the following markup, most of it would already work.

rect {
    fill: blue;
    transition: all .5s ease-in-out;
}

rect:hover {
    fill: green;
    transform: rotate(30);
}
<svg xmlns="http://www.w3.org/2000/svg">
    <rect width="100" height="100" rx="20" ry="20" />
</svg>

The only missing piece is support for CSS transforms on SVG elements (transform: rotate(30)). We might not have to wait too long though. A couple of folks here at Adobe, together with Apple and the web community, are drafting a proposal to bring together CSS and SVG transforms. The proposal would allow you to choose whatever combination of transforms, CSS transitions, and SMIL animations best suits your needs.

Putting it all together, we have an example, demonstrating how different combinations of HTML, SVG, CSS & SMIL can create the same mouse over / click animations. (The svg/css example will only currently work in one of the nightly builds of webkit).

One Comment

  1. March 27, 2012 at 6:12 pm, Matthew David said:

    The CSS and SVG example now works in the current release of Chrome :)