Sara Soueidan - Animating SVGs with CSS and SMIL
Fronteers 2014 | Amsterdam, October 10, 2014
SVGs can be animated with CSS, but they also come packed with their own animation elements that allow us to animate them in ways that are not yet possible with CSS. In this session, we'll go over how SVGs can be animated with CSS, including prerequisites, gotchas, and browser bugs, and then we'll go over the native SVG animation elements and how they can be used, what advantages and disadvantages they have compared to CSS animations, browser compatibility, and a little bit more!
SVG is something of an enigma to me.
It was really born out of the dark times of the web, where I imagine the web was controlled by a group of beardy men sitting in a tepee dressed only in loincloths, and one of them would take a drag from an almighty spliff and say, [INHALING], we should do this in XML.
But despite that, and display no one really using it for years and years, SVG has actually turned out pretty good.
We're kind of rediscovering it [INAUDIBLE] animation in SVG, which we're only just starting to rediscover.
Give a huge, just-before-lunch welcome to Sara Soueidan.
First of all, thank you for being here and for having me.
I hope everyone's awake.
This is going to be a very technical talk.
And it's going to be a very technical talk.
So first, quick about me.
I'm a freelance front-end developer from Lebanon.
I'm also a writer.
I love teaching-- and I forgot to start it.
I love teaching.
And I love writing, so I've combined both into writing a lot of articles and tutorials, most of which have been about cutting edge CSS features, like CSS Regions and Shapes.
And recently I've been focusing a lot on SVG, and hence this talk today about SVG.
I'm also an author and team member at Codrops.
So I'm here to talk to you about animating SVGs with CSS and SMIL.
Now, SVG is an XML based image format for two-dimensional graphics with support for interactivity and animation.
This is the official definition of SVG.
So they are basically XML tags that render images and shapes.
Now, you can select SVG elements, style them, and animate them, just like you would select and style elements in HTML.
You can even inspect individual elements in the dev tools, just like you can with HTML.
And because of that, SVG can be animated using CSS.
So, before we get into actually animating SVGs, we're not going to be going into the technicalities of how to create an animation in CSS.
But we're going to be talking about how to add CSS in SVG first, and then a few buts and gotchas that you should know if you're going to use CSS that will hopefully save you some headaches.
So, SVG 1.1 did not
require any CSS, and therefore it was necessary to present the styles of an SVG using what is known as presentation attributes.
A presentation attribute is a shorthand way for setting a CSS property on an SVG element.
You can think of them as special style attributes, and they even contribute to the style cascade.
So, examples are, in all of the slides that contain any code, the code in blue is the one that I will be talking about, and that you know you don't have to focus on the rest.
So we have width, height, fill, stroke, and stroke-width are examples of presentation attributes.
Now, there are a lot of presentation attributes in SVG that do all kinds of stuff.
But only a subset of these presentation attributes can be set in CSS.
The table onscreen shows all of the attributes that we can set using CSS.
Only a subset of the attributes that can be set using CSS are already present in CSS as CSS properties.
Like, we have opacity, font families, visibility.
So, I want you to hold this thought here, because I'm going to refer to it later in the talk.
So, a subset of presentation attribute is already present as CSS properties.
Now, there are certain attributes, like width and height and position attributes, X-Y-Z, X-Z-Y, we cannot set them in CSS yet.
But in SVG 2, this list, the list of attributes that can be set in CSS, is going to be extended.
And more attributes, we will be able to set them in CSS.
So for a full list, you can refer to this link.
It's being updated, and implementations are being worked on at the time.
So, because attributes can be set as CSS properties, it's now to talk about how you can CSS to SVG.
You can first add them inline inside a style attribute, just like you would with HTML.
Notice how the fill, stroke, and stroke-width attributes are now used as CSS properties.
You can also add the styles in a style tag inside the SVG.
In this case, you will select the element that you're styling using type selectors, like the polygon, ID selectors, class selectors, all kinds of selectors-- kind of, except a few.
And you would style them like this.
You can also include the styles in a style tag outside the SVG if you're embedding the SVG inline, in an HTML document.
And if you want to completely separate the styles from the structure, you can reference an external style sheet.
So, I'm covering these because-- we'll talk about this shortly.
So animating SVGs with CSS.
It's pretty much the same as HTML.
I'm not going to be saying anything new.
If you've worked, animated HTML before, there's only a few things that are going to be new.
Everything else is the same.
So you can apply CSS transitions to an element in SVG, just like you would with HTML.
I have an example here from the iconic icon set.
We have a lamp.
The bulb is generally first initially gray.
And when you hover it, you just select the bulb.
You can select individual elements.
See in the dev tools, you can see and select the elements one by one.
You just select it, apply a style, and hover.
What we're doing here is the stroke-width has increased.
It's becoming thicker.
The color is changing from gray to yellow, and we're adding a light gradient background.
So, this is a simple transition effect.
A lot more can be created.
But basically, CSS transitions are applied to SVG just like HTML.
But most kinds of animations that you're going to apply to SVG are going to probably contain some kind of transformation, be it rotation, scaling, skewing, translation.
Now, SVG responds to the transform and transform origin property just like HTML does.
But there is a major difference between SVG and HTML, which leads to another major difference with transforms.
You see, an HTML element has a box model.
So it has a margin box, border box, padding box, and content box.
And if you're working with coordinate systems on an HTML element, the coordinate system is established on one of these boxes of the box model.
But in SVG, an SVG element does not know the concept of a box model.
There is no box model.
So, if we're going to talk about the transform origin property in CSS, the default value is 50% by 50%, which is the center of the element that you're going to be animating.
In SVG, the default value is 0-0, which is the top left corner of the SVG canvas, not the top left corner of the element.
So, if we have an element, we have an HTML element on the left and a rectangle inside an SVG canvas on the right.
And if we rotate both of them by 45 degrees, the HTML element is going to be rotated around its center, but the SVG is going to be rotated like that.
And this is probably not what you want.
So if you're not going to do any rotations, the default transform origin is not going to be a problem.
But if you are going to do rotations, you're probably going to want to change the transform origin.
Now, to set a transform origin on an SVG element, you can set it using one of two ways-- either using percentage values, the origin is going to set relative to the SVG relative to the element's bounding box, which includes the stroke.
You can think of the bounding box as the smallest box that you can draw around the element-- and also include the stroke in it.
So a percentage value is going to be relative to this virtual bounding box.
And you can also use absolute values like pixels and ems.
But if you use pixels or any other absolute value, it's going to be set relative to the entire SVG canvas.
So if we were to go back to the previous example and set the transform origin to 50% by 50%, it's going to become-- the center of the SVG element is going to be rotated as we expected.
However, we don't always get all rainbows and ponies in web development, right? Some browser has to make a pain out of everything.
So, there is a bug in Firefox.
Basically you cannot set-- it doesn't work if you set the transform origin percentages, it's not going to work in Firefox.
It's a bug.
It's been around for a really long time.
It hasn't been fixed yet.
So for now, if you're going to rotate something in SVG and you want to set the center to-- you want to set the transform origin to the center of the element, just use absolute values.
This is a simple example, a pinwheel, rotating pinwheel.
I've used both percentage values and pixel values to make it work in both browsers.
And then you can use the CSS animation property and key frames, just like you would with HTML.
So the only thing that you should know is about the transform origin, because I've gotten a lot of questions and I bumped into this myself at first.
Like, I have an animation on an SVG element.
It should work, but it's not working in Firefox.
What's the problem? Well, it usually is that they're using percentage values and not providing a pixel value or an absolute value for Firefox.
So we can do a lot of stuff.
We can animate SVGs with CSS.
But SVG comes short in a lot of ways.
There are certain things, limitations to CSS, that you still cannot do things with CSS.
One of these things is animations of attributes such as position and dimension attributes among many others.
Remember how we mentioned before that not all of the attributes can be set in CSS.
So there are certain effects that we will simply not be able to do.
Even shrinking and expanding an element, we won't be able to do it in CSS for now.
It's going to change in the future.
Animations along arbitrary paths-- we currently can't do that in CSS, but implementations, I think, should start in November or so.
So we will be able to do this hopefully next year, because now we have a specification, a link to the specification at the bottom, which is called motion path, which is going to allow us to move elements along paths using CSS.
And then we have morphing paths, or shape tweening.
Now, the reason we can't morph paths is the same reason as the first one, because in order to animate a path, you're going to have to animate the path data.
In order to animate the path data, you're going to have to animate the D attribute.
In order to animate the D attribute, you're going to have to set it using CSS, and you can't do that.
That was deliberate, by the way.
So you can't morph paths in CSS.
So CSS comes short in a lot of places.
We'll talk about those shortly.
But before that, I want to go over embedding SVGs.
The reason I'm going to talk about embedding SVGs in a talk that's about animations is that the way you embed your SVG is going to determine whether or not the CSS animations and interactions, such as hover interactions, are actually going to work or not.
Depending on the technique you use, they may not work.
So SVGs can be embedded in six ways, the first one using an image tag.
If you're using an image tag to embed your SVG, CSS animations are only going to work if they are defined inside the SVG.
So if you're referencing an external style sheet and you have animations in that style sheet, they're not going to work.
Interactions, hover interactions, for example, no, they're not going to work.
You can't interact with an image tag.
The same thing applies for a CSS background image, an SVG applied as a CSS background image.
And you can also embed an SVG using an object tag.
No scripting works for the first two techniques.
It also comes with a default fallback mechanism.
If you can provide text fallback or an image fallback, fall back to a PNG, for example, between the opening and closing tags.
Now, if you're using the object tag, animations and interactions are both going to work only if they're specified inside the SVG.
Same thing as the object tag for the embed tag.
And also the same thing for the iframe except-- well, there are differences between iframe and the object tag and advantages for one over the other, but I'm not going to cover those now.
But it also comes with a default fallback mechanism, which is a plus.
And the last way you can embed an SVG is inline in an HTML document.
In this case, both animations and interactions are going to work whether they are specified inside the SVG or outside it.
So animating SVG with SMIL.
First, let's define SMIL.
It's obviously an abbreviation for-- this is the most boring slide of the talk-- Synchronized Multimedia Integration Language, which is a specification that has many design goals.
Some of these goals is to define an XML-based language that allows authors to write interactive multimedia presentations, and then being able to reuse those interactions in other XML-based languages, such as XHTML and SVG.
OK, so why would you want to use SMIL? If you're going to take anything out of this talk, it's probably going to be this.
We can animate SVGs using CSS.
So why would you want to use SMIL? Well, the reason is that SMIL has some advantages over CSS.
We can morph shapes.
We can move elements along motion paths in SMIL.
We can't do that in CSS.
We have awesome event handling and animation synchronization capabilities, which we're going to see next.
Current browser support-- emphasis on current-- is that they are supported in all browsers except IE, no version of IE, and Opera Mini.
Animation is just part of-- like, a progressive enhancement, and you may not need to provide fallback.
And emphasis on current, because this may change any day.
We may not see SMIL in Chrome-- maybe sometime in the future.
And we may see it implemented in IE.
So this is subject to change.
Now, the best part about SVG is that it's made of human readable tags.
So this is going to make me feel-- it already makes me feel a little useless trying to explain what's going to come next, because a lot of what you're going to see is pretty much self-explanatory.
We have four elements to animate stuff in SVG and SMIL.
The first one is the animate element, which is used to animate scalar attributes over a period of time, like color and positions.
The second one is the animate transform, used to animate transforms, rotations, scaling, translation.
And then we have the animate motion element, which is obviously used to animate an element along a path.
And then we have the set element, which is used to assign values for a certain period of time.
You don't transition or animate from one value to another.
You just set a value for a period of time.
We're going to see an example.
Now, we used to have-- SVG 1.1 did include one more
element, which is the animate color element, and it was used to animate colors, obviously.
But because you can animate colors using the animate element, animate color became kind of useless and redundant.
So it was deprecated and removed from SVG 2.
So if you see animate color used anywhere, just don't use it.
Replace it with animate.
OK, naming animations.
We're going to start with an animation element, using animate element.
First thing you can do for an animation is to give it a name using the id attribute.
But this is not necessary.
You don't need it to make the animation work.
But it will be useful when you're synchronizing animations, when you want one animation to start or end based on another animation, you're going to use the name.
Again, you don't need to set it.
Specifying the target of the animation-- OK, so you have an animation element.
You want to animate something with it.
What are you going to animate? You can specify the target (using the xlink)href attribute, which takes the ID of an element and then it just applies the animation to it.
But if you've used SMIL before or you've read about it somewhere, you've probably seen it done in another way.
Actually, I haven't seen any tutorial online or article that's used the (xlink)href attribute.
All of the others used-- yeah, OK.
One good note.
The target element has to be part of the same document fragment.
You cannot define an animation in a document that references an element in another document.
It would've been nice if it was possible, because then we could separate animations from the actual document, but it's not possible.
So they have to be in the same document.
The other way is you can nest the animation element inside the element that you want to animate.
This is how you will probably see it done online.
Now, the reason this works per specification, as the specification says, is that if you don't specify the target using the (xlink)href attribute, the browser is just going to look for the first ancestor of the animation element and apply the animation to that.
So this is the only reason why nesting works.
You can use this if you want to do some kind of encapsulation, like you want to keep the animation with the element itself.
And if you want to separate them, you can just reference it (using the xlink)href attribute.
Specifying the target attribute-- OK, so we have an element.
We want to animate it.
What about it do you want to animate? Using the attribute name, you're going to specify the name of the attribute.
In this case, I have cx, which is the definition of the center of a circle along the x-axis.
All of these examples are going to be very simple, and just a circle moving around.
And then we have the attribute type.
Remember how I said earlier that some of the SVG attributes are already present as CSS properties? Well, if an attribute is present as a CSS property, you specify the attribute type to CSS.
If it's SVG only, you use XML.
If you use auto or you don't specify the attribute type at all, the browser is going to look in both namespaces and pick the one that it finds suitable.
One note here is that you can only specify one attribute per animation.
So if you want to animate more than one attribute, you're going to have to specify more than one animation element.
You're going to have to define more than one animation.
This isn't-- you know, I wish we could define more than one, but it kind of makes sense considering the other attributes.
So, to define a very simple animation, just moving a circle from one position to the other, we can do that using-- OK, the circle is not moving.
OK, it's just going to move by 400 pixels from the left to the right.
We have the from attribute, the to attribute, initial value, final value, dur, which is the duration, which takes an amount of time, and then the fill attribute.
The fill attribute takes one of two values, remove or freeze.
Remove is the default value, and freeze is basically you specify the end state of the animation.
Do you want that the element to go back to its initial position when the animation is over, or do you want it to stay where it's now? So using freeze, you can literally freeze the animation.
Now, the fill attribute is unfortunately named the same as the fill attribute, which is used to specify the fill color in SVG.
The fill attribute in SVG is generally used to specify a fill color, which is kind of like a background color or something, depending on what you're using it for.
So this is the same name, but don't confuse the two.
If you're using animations, the fill attribute is used to specify the end state of the animation.
The CSS equivalent to the previous is animation-duration, animation-fill-mode, which specifies it's the same as the fill attribute, and then the from and to key frames.
Now, I realize that if you're using CSS animations, you're probably going to use-- if you're using CSS, you're probably going to use CSS transition.
What's wrong with me? You're going to use CSS transitions to move from one value to another.
You don't have to define from and to, just two key frames to do that.
But in SMIL, there is no differentiation between transition and animation.
So just to show an equivalent, I did this.
But you would use transitions in CSS instead.
Repeating animations-- SMIL comes with two attributes-- I told you this talk is going to be technical.
SMIL comes with two attributes that allow you to control repetition and for an animation.
The first one is repeat count, which you can obviously specify how many times that you want the animation to repeat, or you can set it to indefinite, which means that it's going to repeat infinitely.
And the repeat duration, which specifies how much you can restrict the repetition time.
This can be useful if-- well, suppose, for example, you have an ad banner made from SVG.
And you know, everyone knows that ads are annoying, OK.
But you know that motion is going to grab the user's attention, so if you use some kind of animation, you're going to grab their attention to the ad.
You may get clicks, whatever.
But it can get really annoying.
Like, imagine you're reading an article, and there's something constantly moving on the right side bar.
So you can restrict that.
You can have the animation repeat for five minutes or so.
The repeat duration takes a clock value, which is pretty cool actually.
You can set it to 0-1-30-00.
Like, you want the repetition to only last for an hour and 30 minutes, which doesn't make sense, but just an example.
So this is very useful.
In CSS, we have an equivalent to specify the number of repetitions, but we do not have a way to specify the repetition duration.
Controlling animation and begin time-- this is where you start with event handling.
And this is where the values start to get more interesting.
So, the begin value is obviously used to specify when you want your animation to begin.
It takes a lot of values.
I'm going to show examples next.
The restart attribute is useful-- well, suppose you have an animation that starts on click.
And then while the animation is playing, the user decides to click it again.
It's just going to restart.
This is the default value.
It's always going to restart.
So you can change that.
You can set it to never repeat, or you can set it to only repeat when not active.
Like, when the animation ends, OK, you can restart it.
CSS equivalent, none.
We don't have a click event in CSS.
We don't have event handling in CSS.
And don't tell me that we can do that using the checkbox hack.
It is what it is-- it's a hack.
We don't have event handling in CSS, and that's a good thing.
We do have, like, hover active focus, but no click.
Synchronizing animations-- so we have a begin attribute.
We also have an end attribute, which takes the same values as the begin attribute.
So what values can you set begin? How can you specify the beginning time? We have click-- OK.
We have click, focus, and a list of other events that you can check in the specification.
You have click plus two seconds.
I want the animation to start two seconds after the element has been clicked.
Click plus an hour and five minutes and 33 seconds.
You can go crazy with these.
We also have-- this is where the synchronization part.
Remember, I said that you can name an animation so that you can use the name when you're synchronizing.
So in this example, other animation is just the name of another animation.
So you can set that I want my animation to begin when the other animation begins, or I want my animation to begin one second before one minute or one second before the other animation ends.
We also have a repeat function among many others, actually.
We also have a repeat function which allows you to-- like, I want my animation, this element, to start animating at the 10th repetition of the other element.
This may not look very useful if you're just thinking about circles and rectangles, like you're going to see next.
But it is useful when you have a scene and you have a lot of things going on and you want to synchronize between them.
So what I have here is a circle that's changing color indefinitely.
When I click the circle, the color animation is going to stop.
The rectangle is going to start animating one second after the animation of the circle starts, and the circle is just going to move.
So click it, it starts moving.
One second after that, the rectangle is moving.
This is the code for the previous example.
Just look at the ones in blue, because they specify the event handling, and the orange is just the name of the animation.
So we have the second animation which changes the fill color.
In begins when the move animation-- it ends when the first animation begins.
So you can do all kinds of synchronizations with this.
Controlling animation key frame values and pacing-- now, this is where things start to get interesting.
If you're just moving an element or just animating from one value to another, it's pretty much simple.
We had a from value and a to value, and that was enough.
But what if you want intermediate values? In CSS, you can split the animation time into key frames or actually can specific certain times or key times inside an animation, and then you give your element, whatever, a value for every key frame.
Like, for example, if you have a bouncing ball, it's going to start up here, and it's going to come down there.
If it's just a simple transition, it's just going to translate down.
It's not going to be-- it's not going to bounce.
If you want it to bounce, you're going to start with one value, two, three, four, five, six, seven, eight, depending on how much you want.
So you're going to have to specify the intermediate values.
In CSS you do that, using key frames in blue, using the value specifying a value for each key frame, the ones in green.
In orange, we have the timing function.
You can control the pacing of an animation per key frame using custom easing in CSS.
Now, I deliberately did this-- I talked about CSS before SMIL because what helped me understand SMIL pacing and this kind of animation was when I just compared it to CSS, because other than that, the attributes didn't make a lot of sense for me at first.
So this is the SMIL equivalent.
We have a values attribute which takes a list of values-- the beginning value, the end value in the end, and any intermediate values in between.
It's a list of semicolon separated values.
And then we have the key times, which are equivalent to the key frames.
But instead of setting them in percentages, you're setting them as ratios, fractions between 0 and 1.
And then you have the key splines.
I'm going to talk about this again later.
The key splines are basically just the timing functions.
And the calc mode attribute is necessary.
You're going to have to set it to spline if you're going to use any kind of custom easing.
For an animation, you're going to have to set the calc mode to spline.
Calc mode takes one of four values-- linear, the animation is going to be linear.
Discrete is similar to the steps function in CSS.
Paste is similar to linear, but with some differences.
I'm not going to mention those because there would need more time.
And then you have spline.
If you use spline, then you can use custom easing in your animation.
Key times are fractions, not percentages, as mentioned before.
The number of key times equal the number of values, of course.
For every key time, you specify a value, but the number of key splines is less.
So basically, it makes a lot more sense for me in SMIL than it does in CSS.
Like, if you want only three key times-- 0%, 50%, and 100%, then you have two intervals.
You specify a custom function, a custom easing for each of these two intervals.
Three key times, two intervals enhance two key splines.
The number of key splines or custom functions is one less than the number of key times.
This makes more sense for me because, you know, key times make intervals, and you specify custom easing for intervals.
In CSS, it's not like that.
And the key splines use control points and not the busier function.
So this is better explained here.
In CSS, if you're going to set a custom easing, you're going to use the function at the bottom.
In SVG or in SMIL, instead of using the functional notation, you just use the coordinates inside of it.
So if we were to go back here, the key splines are just coordinates of the control points and are semicolon separated.
I think that the code is a lot clearer than what I just said.
So this is the ball animation.
Click it, and this how it-- all of the intermediate values and custom easing has been defined using SMIL.
We have an animate example.
So as I mentioned before, you can animate things in SMIL that you cannot animate using CSS.
One of these things is the path data.
So if you have a path that has a circular shape, and you want to animate it into a rectangular shape, for example, like this-- credit for this example goes to Noah Blon.
He has an article on CodePen that explains exactly how this is done.
So basically how it is done is, you have a path.
You start with a value which is a circular shape.
The data defines a circular shape.
And then you have the final data defines a rectangular shape.
And in between, you have a triangular shape.
So the way you do that, the way you animate from one shape to another, is using the animate function.
The attribute name is D. You're
animating the D attribute, the data of the path.
And then you just give it a set of values that you want it to go over, and it just animates from the first to the last going through the intermediate ones.
Path tweening, shape tweening in SMIL is very simple, as you can see.
And if you want a full tutorial, refer to Noah's article on CodePen.
animateTransform animation-- so the animateTransform element, you specify that the attribute name that you're going to animate is the transform attribute, obviously.
And then instead of-- well, transforms, there's a lot to say about them.
So let's see how I can summarize that.
So instead of giving-- you have a from value and you have a two value.
You're animating from one value to another.
I'm not going to be getting into intermediate values now.
So instead of starting with a rotate function and then ending with a rotate function, you're going to specify the type of rotation in the type attribute, the type of the transformation and the type attribute.
If you're doing a rotation, use rotate.
If you're doing a translation, use translate, et cetera.
And then in the from and to-- how do I say that? The values are the same values that you are going to use in the rotate function.
I know I'm not making any sense at all.
So if you want to know everything about SVG transformations, you can refer to this article.
It's a long article I've written, part of a big guide.
Everything you need to know-- syntax, values, how they affect the coordinate systems in SVG, everything-- refer to this article.
A set animation example-- what I'm doing here is this is a rotating square again.
So what I'm doing is just I want to set the color to blue for three seconds.
You can, of course, set visibility and many other things.
Get creative as much as you want.
It's set to blue for three seconds, and then it's back to pink.
There are a lot of use cases.
This is just the simplest kinds of examples I'm using here.
Animation along arbitrary paths-- well, using the animateMotion, you're going to animate an element along a path.
But in order to do that, you're going to have to specify the path that you want the element to take, right? So there are two ways you can specify a path-- either using the path attribute here, which just takes the data of a path, the syntax is very similar to the D attribute.
You just give it a path data, and it's going to use that to animate an element.
Or the other way has an advantage.
If you use this one on the left, the path is not going to be drawn.
So you just have an element that's just going to animate along some path.
But this one has an advantage here is that you can use the end path element.
It's nested inside the animateMotion element.
And it refers to a path that is defined somewhere else.
So the path-- like the one at the bottom here, it's rendered on the screen you can see it-- and then you want the element to animate along it.
Now, there is actually a lot to say about animations along motion.
I'm going to just the basics, but more details will be coming soon.
I'll tell you about those at the end of the talk.
So in this example, if I'm using the path attribute, the circle is just going to animate along a path without you being able to see what the path is.
And with the second example, I'm referencing a path that already exists, and then I'm animating the circle along that path.
But what if what you're animating has orientation? Like, what if you're animating a car? This is the default behavior.
If you have a car and you're animating it-- you know.
So what we're going to have to do is we're going to have to change the orientation of the car so that it adapts to the shape of the path.
We're going to have to change the orientation of the car so that it adapts to the path.
So in order to do that, we have the rotate attribute.
The rotate attribute, if you set it to auto, the browser is going to change the orientation so that it matches that of the path.
So we've gone one step further here, but the circle is animating inside.
I want it outside.
So in order to do that, you can change the value.
You can use the auto reverse, which is basically the same.
It's going to adjust the orientation, but it's also going to flip the car by 180 degrees.
But for those of you with a sharp eye, you're going to notice that the car is moving backwards.
So in order to move it forwards, we're going to use transforms to flip it again.
You know, in CSS and in SMIL, if you scale an element by minus 1, it's not going to be scaled.
It's going to be flipped.
So in order to flip the car, I'm going to transform it, and we end up with this.
[APPLAUSE] Animating text along arbitrary paths is a little different.
We're not going to be using-- this is the last example, so just hang on a little bit.
Animating text along an arbitrary path is different because we're not going to be using the animate motion element.
We're going to be going back to the animate element.
So the way you do that is first, we're going to put the text on an actual path.
To do that, we're going to use the text path, conveniently named, of course, as everything else.
It's going to reference a path.
And then it's going to place the text inside it on that path.
Cool? OK, so the next thing we're going to do, we're just going to animate the text offset.
So instead of starting at the beginning of the path, it's just going to be animating.
So this is what we end up with.
I've used some custom easing just so that it slows down at the end.
And that's all you need to animate text along a path.
I'm going to go over embedding techniques again, not over each one.
The table has already seen-- but just to show that SMIL animations are going to work in all cases.
The only thing that's not going to work is the interactions.
Click interactions, hover, anything-- nothing's going to work when the SVG is embedded as an image tag or a CSS background image.
And before I say thank you, I know that I said a lot of things that I could have elaborated on.
There are a lot of details, a lot of gotchas and stuff.
So this talk used to be very long.
I had to shrink it a lot.
I'm not sure if I'm overtime already.
So I'm going to be sharing-- after my talk, I'm going to be sharing this version and the extended version.
And we have something-- I've written a 9,500-words guide.
It's all about SMIL animations, all the details that you want.
We're going to publish it probably on Monday on CSS-Tricks.
So if you're following me, Chris Coyier, or CSS-Tricks, you're going to be updated.
If not, I'm going to tweet the link to the article with the fronteers14 hashtag.
So if you want, you can check that article out later.
And now, thank you.
[APPLAUSE] That was incredible.
That was like on the matrix.
No, that was like being in the Matrix.
I had the thing plugged into the back of my head, and it was just like that, and I was like, I know SVG.
So, what drew you to SVG? It's something that's been-- I mean, it's been around for ages, and it's been on my to-do list to learn.
And I've never really, really got there.
What drew you to SVG? Well, I started seeing it everywhere.
Like, especially when it came to Icon Fonts, and everyone was like, OK, Icon Font doesn't look or behave really great on retina screens, or whatever.
So everyone was starting to use SVGs.
And I had no clue about SVG.
I didn't know anything.
So I had it on my to-do list for months.
And then I had a talk at CSS-Conf, and I wasn't very excited about the talk topic that I had.
So I decided, OK, what better way to get excited about something new and learn something new about the same time.
So I changed the topic to be about styling and animating SVGs, started researching, and I got hooked.
So you decided just to throw away your talk and you thought, well, I'm just going to learn SVG and then write a talk on it? Yes.
OK, fair enough.
That's very, very-- what's the state of performance in SVG? Do we have hardware acceleration, and how can I deal with performance issues? CSS animations-- this used to be part of the talk before I deleted it.
CSS 3D-- you can use CSS 3D transforms on SVGs, but they are not hardware accelerated in Chrome.
There is some hardware acceleration in Firefox, but not in Chrome.
That's when it comes to animations and transforms.
Performance is a very wide topic, actually.
Depending on the technique you use and depending on the SVG, the content of the SVG, it may be fast, may be slow.
It may be good on desktop, it may be bad on mobile.
So the first thing I'm going to do-- actually, it's the first thing on my to-do list after this conference-- is I'm going to be doing a lot of performance tests, and I'm going to be sharing those as soon as I have them.
Are there particular performance gotchas? Are there properties to watch out for, whether it's animation or just rendering in general? No.
I think it's just rendering in general.
Is there a way-- do the profiling tools in browsers, do they pick up on this stuff? Could you rephrase that? Sorry.
In Dev Tools, in browsers, are they SVG aware? Well, in what sense? Like, if you have an SVG, it's just going to-- well, the only profiling that I've done was just to see the loading time, because all I did was, I replaced an SVG.
I was referencing it inside an image tag, and so I decided to reference it in CSS, using Base64.
And it slowed my page load time by one second.
So that's the only thing that I saw in the dev tools.
But I'm going to be using webpagetest.org,
and Paolo is-- he's going to be helping me with this.
I learn a lot from him.
It feels like we maybe need browsers to step up a little bit in terms of telling us which parts of the SVG are causing issues.
Internet Explorer, actually, with IE9, they really impressed me with their SVG rendering.
Like, it was really fast.
It seemed like they'd pull a lot of thought into the performance side.
But they didn't do smile, or SMIL, however it's pronounced.
Why did they drop the ball there? Was it deliberate? I don't know.
Any idea if they've got plans to do anything with that? Well, you know that page where you give feedback about the features that you want to see implemented in IE, SMIL animations are one of the most requested ones.
So we may see them implemented.
That's why I had the emphasis on current browser support.
It may change any time.
I was surprised to see how SVG animations were so high compared to, say, the web animation spec that we heard yesterday.
How does the stuff you were talking about interact with the web animation stuff that we heard from Rachel yesterday? Well, I'm not very familiar with the details of the web animations API.
The only thing that I knew, which I learned from a conversation with you and [INAUDIBLE] a while back, is that the web animation is going to provide-- it's going to be kind of like a common denominator.
It's not actually going to replace SMIL.
SMIL is declarative.
Web animations are going to be imperative.
And well, I still don't know about the future because I've never compared the two.
So I don't know.
So SMIL still has an advantage over that.
Which cases? The image tag and the CSS background image.
Actually, there's a question that just occurred to me.
Maybe you'll have the answer, because I certainly don't have the answer.
When would you use an object tag versus an iframe verses inline, I guess, for SVG? Well, inline, the first thing that comes to my mind about and inline is I would use it if the SVG-- well, the SVG itself is not really big, because some SVGs are really big, and I wouldn't want to clutter my HTML with it.
And again, as I mentioned before, it depends on what you're doing.
So if you can, if the best way to implement it and animate it is using inline without cluttering, just use inline.
The object tag versus iframe, they are very much similar.
But I think that-- I don't use iframes a lot, honesty.
So object tag has an advantage in this way.
So, taking an experience I had from Lanyard, I had what I thought was a great idea, that I was going to replace all of the-- for different conferences, we got the flag of the country the conference is from.
I thought if I'm going to replace all of those with SVG, because that's going to be better and it's going to work on a screen of any resolution.
But I got tripped up because-- and I can't even remember what country it was, but one country had their flag has, in the middle of it, a crest which has a lion.
And on the lion's neck, there is a flea.
And then the flea has a very complex crown.
And it was so much detail that this one flag was a megabyte in size.
When you decide to use a PNG versus SVG? Well, I guess that if the SVG is simple, there isn't a lot of markup and a lot of information in it, then it may be better than a PNG.
But if the SVG contains a lot of details and a lot of markup, it can become really heavy.
So PNG would be a better alternative.
So SVG has-- you can create definitions for particular things, such as animations and gradients.
And you can also have paths as being part of that.
And you were saying that you referenced that from the documents, but it has to be the same document.
If the SVGs are inline, can I reference between them, or is it still very much a sandbox environment? Well, if the SVG is inline, well, the animation would still be inside the SVG, right? So it would work.
So if I had two inline SVGs on my page, I could reference the animation from A to B? I'm not sure.
I think it works in Chrome, but I don't know if we're breaking the specification by doing that.
If you have two inline SVGs and you're referencing an element from the other SVG in the-- I haven't tried that.
Yeah, as I say, I think it works in Chrome, but I don't know if that's-- I have to try that.
I don't know if it's a good thing that we do that.
Which features of SMIL do we need in HTML? Like the quickest, if you were giving a priority to them, what do we need to be able to apply to arbitrary HTML elements via CSS, or whatever makes sense? I don't understand the question.
No, it's OK.
I kind of talked all over that.
If there's a feature you could take from SMIL now into normal HTML, so you could apply it to other elements-- Motion along a path would be my first guess.
But we will have it in CSS sometime later.
So maybe path tweening, because I'm not really sure what the issue is and why specifying and using paths in CSS is still not implemented.
I'm not sure if it will be, or if it will, when.
So moving that into HTML would be cool.
Defining and using paths in HTML would be powerful.
One of the things I hadn't seen before was the declarative way of activating animations based on events.
Is it possible to trigger one element animating from clicking another element? Yes.
How is that done? Is there a separate attribute for that? Well, there is the begin attribute.
And it depends on the values that it takes.
It takes event values, and you can combine those with clock values.
And you can also use-- well, what exactly do you want to do? Begin an animation when the other one begins? Well, more that if I click on the blue circle, the green rectangle starts rotating.
So you want the blue circle to animate too, or not? No.
No, in that case, I don't think that's possible, because you can synchronize an animation based on another animation, not based on another event, as far as I know.
I may be wrong.
I wonder if you could hack that behavior by creating, like, an empty animation on the circle.
I guess, would that work? That's a pretty cool idea.
Yeah, if you wanted to-- because I suppose the benefit of making it declarative like that is it would work in an image element.
Actually, is that true? If you've included your SVG in just an image tag, does it get that interactivity? Do you still get the click effects? No.
You can't interact with it.
So even if it's declarative-- Even if it's SMIL, it's not going to work.
That makes sense.
With shape tweening-- I'm actually from a Flash background originally.
Actually, the first two talks I gave at Fronteers, my slides were made in Flash.
I didn't tell many people that.
But with the shape tweening, how does that work? If I'm transitioning from one shape to another, is it like the first point in the first path moves the first point-- They have to-- they need to have the same number of points, defining points, and they need to be in the same order.
This is very similar to CSS shapes, actually.
Because in CSS shapes, you have the shape functions.
They are made up of points.
And in order to animate from one shape to another, they have to have the same number of points, because the browser is actually animating the points, the coordinates of the points, and just changing their position.
So if I just took, I guess, any two SVG shapes, there's a high chance that they might sort of overlap in a transition, depending on which order the path was defined.
The order, yes.
You need to have the same number of points from the beginning to the end.
It's not going to work otherwise.
So when you're authoring SVG, are you in the text editor only? Or is there any kind of graphical environments? No.
Well, my SVG workflow isn't exactly the perfect ones.
I start with Illustrator.
I have very limited Illustrator skills.
I don't think I have any skills at all, actually.
I keep Googling stuff that I want to do.
So you create it.
Then you export it.
And then I optimize it.
I haven't automated this yet, because the SVG optimizer tends to break SVGs if you're going to use it.
So I just move the exported SVG into an online editor, I optimize it, and then I export it again as an optimized version.
I open it in Chrome.
And if I need to add any animations or stuff, I'll just do it in the text editor and preview it in Chrome.
To be honest, I have a very similar workflow.
I use Inkscape, which is not even as nice.
I don't like it.
Yeah, it's horrible.
The lines are ugly.
The one reason I use Inkscape is that the format it saves in is SVG, so I can kind of skip between the text editor and Inkscape.
But you're right, the price you pay is you have to use Inkscape, which is a big price.
So why are some of these presentation properties-- what made some of them presentation property only? Why did only some of them get CSS equivalent? I don't know.
Some of them are still being exported into CSS.
Like, CSS transforms, I actually learned that the CSS transform specification is derived from the transforms in SVG.
So this is being done with a lot of other things, including their most recent one, the motion path.
So work is still being done.
And actually, also, if you're going to be transforming SVGs.
If you're going to be chaining transformations, don't you SMIL.
It's going to give you a big headache.
So use CSS transforms instead.
So things like path specifications, the D attribute, are we getting them in CSS as well? Not yet.
I'm not sure why.
Dirk and Tab were having a conversation on Twitter once.
And Tab asked him, wasn't it because of the grammar that we're still not implementing it? So it's something that has to do with grammar and stuff.
I find that a lot of the SVG minifies, they tend to-- they seem to prefer presentation attributes over CSS.
I don't know why.
That was going to be my question.
Because it seems to me, like, you could get a smaller file size by a better [INAUDIBLE].
I guess maybe it's just an area that hasn't been explored.
I'm not sure, actually.
I don't know why I would prefer presentation attributes.
I would rather separate the styles from the structure.
And then, this is a kind of-- Also you can have the specificity problems with presentation attributes.
Like, presentation attributes is the lowest one in the cascade.
It can be overridden by any other-- you would expect that a presentation attribute is more specific than inline styles, for example.
But they're not.
The only thing that a presentation attribute is going to orverride is browser stylesheets, default browser style sheets, and inherited styles.
Other than that, they're not-- so you may end up with specificity problems if you don't know this particular thing.
So even if I've applied some stuff, just linked to a class name like the lowest specificity in CSS, that's going to override the presentation styles.
That's kind of backwards of what I thought it would be.
Thank you very much.