CSS: Animation Using CSS Transforms
The examples on this page will work properly in Safari, Chrome and Opera. In Firefox prior to version 4 you will see the transforms, but without any animation. Transformation effects also work now in Internet Explorer 9 using the -ms- vendor prefix.
The implementation of animation in CSS involves setting up a transformation to take place in response to a mouseover or other event. Then, rather than applying the effect instantly, we assign a transition timing function which applies the transformation/s over a set time period.
Firefox and Opera now support these transforms with an almost identical syntax - just replace -webkit with -moz or -o in the examples below and you will see the same effects. And you can use -ms to enable transformation effects for IE9.
Introducing CSS Transformations
The effect of a CSS Transform is to modify the appearance of an element in the browser by translation, rotation or other means. When defined in a style sheet transformations are applied before the page is rendered, so you don't actually see any animations taking place. Transforms can also be applied as a mouseover or similar effect which you can see in the next section.
Apple's proposal for CSS Transformations calls for the ability to change the perspective and work in three dimensions, but that's some way away yet. Even the features demonstrated here won't appear in other browsers until they're approved by the standards body who are still quibbling over CSS3 modules.
Below we've placed four identical DIV's styled as a 100 x 60 pixel box with a 2 pixel border. Subsequently, each element has been transformed in some way using the -webkit-transform property as follows:
| box 1 | Translated to the right: -webkit-transform: translate(3em,0); |
| box 2 | Rotated 30 degrees with the clock: -webkit-transform: rotate(30deg); |
| box 3 | Translated to the left and down: -webkit-transform: translate(-3em,1em); |
| box 4 | Scaled to twice its original size: -webkit-transform: scale(2); |
Without the translations, and the red border on the second box, you would see just four identical boxes labelled one through four. What you see in supported browsers (Safari, Chrome, Firefox, Opera), however, will be more like this:

Of note is the fact that the text is still selectable in transformed elements, even when rotated, and that scaling an element affects other properties including border widths and font sizes and not just the dimensions.
Animating your Transforms
While CSS Transformation in itself is a powerful tool for developers (though I shudder to think what would happen if it was more widely available), the ability to animate the same effects using -webkit-transition is far more exciting. Move your mouse over the following four boxes for a demonstration:
What you see above is the four boxes from the previous section, in their default states. When you mouseover any of the boxes, however, the CSS transformation is applied as a one second animation. When the mouse moves away the animation is reversed, taking each box back to its starting position and state. And we achieve this without using JavaScript - only HTML and CSS!
If you think that's cool, realise that CSS Animation can be applied not just to the transforms, but also to other CSS properties including: opacity, colour and a bunch of other properties.
In the next example the box on the left begins as small and green with square corners, while the one on the right is larger, with a red border and rounded corners. Hovering over either of the boxes will trigger an animation that makes box 1 take on the appearance of box 2 and vice versa.
Again, we're still only using HTML and CSS to make this happen. Without CSS Transforms the two boxes will still change their border-color, and possibly also the border-radius, but it happens immediately rather than as a one second animation.
For more advanced examples you can read our new article on using JavaScript to trigger the animation.
Multiple Transforms on one element
To apply more than one transformation to a single element simply list them one after another separated by spaces. The submenu for example at the top right of this page has the following styles:
<style type="text/css">
#submenu {
background-color: #eee;
-webkit-transition: all 1s ease-in-out;
-moz-transition: all 1s ease-in-out;
-o-transition: all 1s ease-in-out;
-ms-transition: all 1s ease-in-out;
transition: all 1s ease-in-out;
}
#submenu:hover {
background-color: #fc3;
-webkit-transform: rotate(360deg) scale(2);
-moz-transform: rotate(360deg) scale(2);
-o-transform: rotate(360deg) scale(2);
-ms-transform: rotate(360deg) scale(2);
transform: rotate(360deg) scale(2);
}
</style>
This means that when you hover over the submenu, it will change colour, rotate and double in size over a period of one second as shown here:
![]() |
<=> | ![]() |
These effects are now available in the latest public release of Safari, so in principle all OSX users will be able to see these effects. Whether it's a good idea to add them to your website I'll leave up to you.
Update: Thanks to misterbisson those without WebKit can now see a screencast of the menu animation:
Animations in action
Now here's another example of the kind of fun we can have in combining different effects into single animation. Perhaps you can already work out what's going to happen based on the CSS?
<style type="text/css">
#outerspace {
position: relative;
height: 400px;
background: #0c0440 url(/images/outerspace.jpg);
}
div.rocket {
position: absolute;
bottom: 10px;
left: 20px;
-webkit-transition: all 3s ease-in;
-moz-transition: all 3s ease-in;
-o-transition: all 3s ease-in;
-ms-transition: all 3s ease-in;
transition: all 3s ease-in;
}
div.rocket img {
-webkit-transition: all 2s ease-in-out;
-moz-transition: all 2s ease-in-out;
-o-transition: all 2s ease-in-out;
-ms-transition: all 2s ease-in-out;
transition: all 2s ease-in-out;
}
#outerspace:hover div.rocket {
-webkit-transform: translate(540px,-200px);
-moz-transform: translate(540px,-200px);
-o-transform: translate(540px,-200px);
-ms-transform: translate(540px,-200px);
transition: all 2s ease-in-out;
}
#outerspace:hover div.rocket img {
-webkit-transform: rotate(70deg);
-moz-transform: rotate(70deg);
-o-transform: rotate(70deg);
-ms-transform: rotate(70deg);
transform: rotate(70deg);
}
</style>
.rocket
If you're using Safari 3 you may notice some problems with the animation, particularly when it reverses after you move the mouse away, but in the latest version of WebKit it's already much smoother. Also the animation in Opera is a bit erratic, with not all the elements being animated.
The dotted outline that appears during the animation shows the placement of the DIV containing the rocket image. This DIV translates across the screen while the image inside is rotated. Simple!
For the browser-impaired what's happening is that when you move the mouse over the space background, the rocket translates from the bottom left to the top right over a period of 3 seconds (translate()) and also rotates 70 degrees in a clockwise direction over the first 2 seconds (rotate()). The effect is rudimentary, but shows the potentional.
To have more control over the animation paths and timing, you can set up WebKit Keyframes. They also allow the animations to run automatically rather than in response to mouse events.
Multiple timing functions
In this example we are applying four different transitions using four different timing functions.
When you :hover over the area to the right the blue box will spin, change color from red to blue and move from the top left of the containing box to the bottom right over two seconds.
The first thing you will notice is that that the movement of the box appears to be curved rather than straight. That's because we've used the ease-out timing function for the horizontal translation and ease-in for the vertical.
The other feature is that the colour change from blue to red takes place over the first second of the two section transition, followed by the rotation which takes place over the second second.
The trick to this is that instead of defining the -webkit-transition as a single property, you can break it up into component parts. We've also made use of -webkit-transition-delay which allows you to set the starting point of different effects.
Here are the relevant CSS statements:
#block {
...
background: blue;
...
-webkit-transition-property: left, top, background, -webkit-transform;
-webkit-transition-duration: 2s, 2s, 1s, 1s;
-webkit-transition-timing-function: ease-out, ease-in, linear, ease-in-out;
-webkit-transition-delay: 0, 0, 0, 1s;
...
}
#stage:hover #block {
left: 100px;
top: 100px;
background: red;
-webkit-transform: rotate(360deg);
}
The rules affecting the background colour transition have been highlighted.
Firefox does not appear to support the
transition-delay option requires units to be specified even
for zero values in -moz-transition-delay, so 0s, 0s, 0s, 1s will work for the example above.
Hover over one element to affect another
A couple of people have asked about triggering animations in relation to a click or hover event elsewhere on the page. With JavaScript this can be done by using an event handler to set or change the className of the element to be animated, and to have a transformation or keyframes associated with the new class.
Using CSS there are some options for targeting related elements. These involve selectors such as the > (child), + (adjacent sibling) and ~ (general sibling) combinators.
The preceding examples all required a direct hover event either on the element itself or on its container, wheras in this example the blue box is animated only when you hover over its sibing, the red box:
The relevant CSS code is as follows. Note that we are using the + adjacent sibling combinator to target #box2 when #box1 experiences a hover event. The ~ combinator may be more flexible in letting you target elements that are further away from the triggering element (some examples).
#box2 {
position: absolute;
left: 120px;
...
background: blue;
...
}
#box1:hover + #box2 {
-webkit-transform: rotate(360deg);
-moz-transform: rotate(360deg);
-o-transform: rotate(360deg);
-ms-transform: rotate(360deg);
transform: rotate(360deg);
left: 627px;
background: yellow;
}
Of course we can still animate the first box at the same time as targeting it's sibling or siblings:
Just be sure not to move the hovered element out from under the pointer or the animation will stop/reverse.
These examples work more or less as intended in WebKit (Safari, Chrome), Firefox and Opera. They may also work in IE10 or higher - if anyone can confirm that please let us know.
References
Translations
- Belorussian - by softdroid
- Czech by Alex Novak from bizow.com
Related Articles - Transforms and Transitions
- Animation Using CSS Transforms
- Transition Timing Functions
- 3D Transforms and Animations
- Bouncing Ball Animation
- Controlling CSS Animations
- CSS Animated Fireworks
- Infinite Animated Photo Wheel
- An actual 3D bar chart
- Photo Rotator with 3D Effects


Luca Belmonod 26 May, 2008
hem, i can only see the menu changing color,
do i have to disable some ad protection, or script protection?
any way i don't want script for transition and animation
thanks
hem, you're using Firefox and not Safari
Ain 15 September, 2008
There's another CSS3 transforms test case available from flash tekkie.
Great feature indeed, let's all hope it gets finalised into CSS3 standard.
pj 18 May, 2009
actually . . . all your web-kit transformations work in both google chrome2-beta as well as apple safari4-beta.
funny part about it is this . . . apple wants 3-d animation with web-kit . . . and their 2-d transformations are not as smooth as chrome's transformations.
(www.nabble.com/Apple%27s-Proposal-for-CSS-Transformations-t4760870.html)
Erik K Veland 12 August, 2009
Is there a way for the animation to be triggered on pageload instead of on a hover? Preferably without javascript.
I still have to investigate this, but I'm fairly certain that you'll need to use JavaScript to add an onload event. Otherwise when the page has loaded the transforms will have already completed.
eike 5 October, 2009
How to trigger an animation onload?
I want to animate opacity from 0 to 1 upon load. I got this working with minimal support from javascript, but I'm looking for a solution that is purely css based.
I want to get rid of the javascript for this effect. Any hints someone out there?
shoaib hussain 20 December, 2009
applied this to my blog just yesterday and folks are already asking me how m i doing it? lol i routed them this way .thnx
A. H. M. 7 May, 2010
This also works with Google Chrome perfectly (or at least the 5.0 beta).
Naresh kumar 20 May, 2010
Hello sir i am using Firefox explorer. This animation is not working for me. When I will take the mouse over to it. Its changing the color only but I want to increase the size also. Please help me.
Both the colour and size will change in mouseover in Firefox 3.6, but instantly rather than through a transition. In version 3.7 transition timing functions will also be supported.
Alaor 30 May, 2010
Why did you left opera out? Your examples looks good in Opera, using the -o- prefix.
In the very latest version of Opera for OSX (10.53) the transforms will work, but only some of the animation. The animation is also still a bit jerky.
Arthur Abogadil 16 September, 2010
Found this link from an Smashing Magazine article about inspirational sources of Typhographical layout, nice post.
Nicolás Almería 13 January, 2011
Excelent post but this controls it doesn't work in IE..
IE9 will support some CSS3 2D Transforms, but probably not the animation effects.
David 19 January, 2011
Thanks for your css treaks. Now I have my own css animated header!!! Take a look at www.polimalo.com/
Awesome!
css transform 9 March, 2011
I've built a jQuery plugin that makes it easy to use css transform in a cross-browser way: github.com/lrbabe/jquery.transform.js
shibbydib 13 March, 2011
Let me tell, you this is all crap. None of these work the same across any browser, not even Chrome/Firefox, latest versions of both support CSS transforms remotely the same. This is what is supposed to replace Flash? Give me a break.
Gene Borman 10 August, 2011
I suppose we will just have to wait until IE catches up with the rest of the world. Any odds given as to when?
The rumour is that -ms-transition is coming in IE10
Fokkelien 24 September, 2011
The animations work very well, even in IE 9 & 10. Firefox is OK, but in Chrome and Safari they are really beautiful.
Good to know. Dank je wel
Freelance Front End Developer 4 October, 2011
Knowing when the transition has ended (using the transitionend event) is really useful - you could potentially use it to chain effects across multiple elements.
Dave 17 November, 2011
Can't wait for -ms-transition to become available, why does IE always have to be two steps behind other browsers!! I still can't get over why browsers all come up with their own prefixed versions of transform, transition etc etc. It makes it a nightmare to remember! I end up having to use sites like www.cssrotate.com to get the job done lol!
Saeed Neamati 1 February, 2012
Man, I just know that I hovered on the rocket image, and it raised to the orbit. I can't believe it that the next generation of CSS and web technologies can provide us with such a powerful design capabilities.
Thank you indeed.
evolution 11 February, 2012
Good tutorial, thanks to this i made a css3 digital clock design with css3 animation e transition
explosivelab.blogspot.com/2012/02/css3-clock-design.html
bouchaib 3 March, 2012
nice trick, however the css code is invalid !
Brad 21 March, 2012
Great write up. They also work smoothly in FF 11.
Yes, everything works now in Firefox except for the transition-delay setting in the last example.
Azuki 23 March, 2012
This is a great tutorial. Thanks for breaking it down so well!
I have a question about #6 above (Hover over one element to affect another). In your example, is there a way to also trigger an animation for Box#1 while also still animating Box#2?
I've tried using the combinators ~ and + without success (both elements are siblings of the same parent div). I'd really appreciate any ideas you have about accomplishing this in CSS!
Thanks!
I've added an example of this now
André Reitz 27 April, 2012
Great and detailed post!
Transactions that animates the background position doesn't work on Opera. Just for information.
And it seems to have no alternative solution!
If you guys find out how, please let me know!
thx
Website Design Bangladesh 23 May, 2012
has anyone found a solution to autostart the animation. I've seen a website where clods flow from left to right and doesn't depend on mouse action. apparently the guy didn't use javascript for this. Wondering how he did it!
The CSS solution for auto-starting an animation is to use keyframes
Hannes Gerlach 16 June, 2012
Hello, I've found your post unbelievable helpful, but there is one question I couldn't figure out after all. In number 6. you explained how to work with hovering and I used it to give extra information while hovering over a adjecent <div>.
What I would like would be the option for the information to stay visible for the event that the div is clicked. And for the information to vanish again after clicking for a second time.
I imagined that it could work as it works with links( :visited etc. ). Sadly thats not the case. Is there a known possibility or an other mechanic I could try?
You will need to use JavaScript - an "onclick" event that changes the 'class' either of the element that is clicked or the one that moves, and then changes it back on the next click.
josinhoka 9 July, 2012
@Luca add this line on firefox and will work fine -moz-transition-duration: 1s;
nemo 17 July, 2012
I think it'd be best if you simply specified always using units. Your advice at present suggests using -moz-transition-delay: 0s, 0s, 0s, 1s only.
Since Firefox has unprefixed in nightlies, not using units everywhere means people will do "transition-delay: 0, 0, 0, 1s" and at some point that will break.
The exact reading of the spec seems pretty clear that unitless is not an option - so in fact the syntax you are using is a bug. At some point we'll want to get away from vendor prefixes, so best to fix this now.
So far it's only Firefox that 'drops' the transition-delay value of '0' for having no units specified. The reasoning seems to be that in a potential future short-hand property the '0' could be ambiguous with a numeric value for 'iteration count' or similar.

So yes, to be safe you should use '0s' instead of '0' as that will work for all browsers currently supporting transitions.
Ben Lozano 2 August, 2012
This is an interesting article. I have to take issue with the fact that you called some of the transitions shown "animations". CSS3 defines "animations" as well as "transitions," and the two are not interchangeable.
Animation: "the rapid display of a sequence of images to create an illusion of movement".

You can create animations using either CSS Transitions, as shown above, or with CSS Animation (using @keyframes). A "transition" is simply a change of state which can now be stretched out (i.e. animated) using transition timing functions.
markosansa 18 December, 2012
Good code but what's about is browser's compatibility ?
The transformations (shift, rotate, scale) are all working in IE9, but not the animations. In IE10 the animations should also work.
Mark 9 April, 2013
Take a look at this one to see how far you can go with ONLY css
markqian.com/css3
DevMan 20 April, 2013
Works in IE10...