Prerequisite knowledge

Basic HTML and CSS skills.


Additional required other products

For this tutorial, you will need a text editor and a web browser.

User level


If you've been reading up on the latest in CSS-related techniques and tips, then there's no doubt that you've probably come across articles, blog posts, and tutorials of all sorts that have covered the topic of CSS3 transitions, which allows property changes in CSS values to occur smoothly over a specified duration. The module in the W3C specification that covers CSS3 transitions is now close to attaining Candidate Recommendation status, which means that this is a CSS3 technique that is now a staple in the toolbox of many modern CSS developers.
This article covers CSS3 transitions in-depth. I hope you'll come away from this article with a more rounded understanding of CSS3 transitions, along with a few practical tips and techniques to help you implement this feature in new projects.

Transition syntax

The syntax for transitions is usually expressed in shorthand, which I strongly recommend for brevity and maintenance. I'll get to that later in this section, but for now I'll introduce a simple transition example using the longhand notation:
.example {     transition-property: background-color;     transition-duration: 2s;     transition-timing-function: ease-in;     transition-delay: 1s; }
Note that, for brevity, this article shows all code examples without vendor prefixes. When you use the code, be sure to include all the necessary prefixes when using transitions, and always include the standard unprefixed rules last.
Following is a breakdown of the above example.
The transition-property line defines which CSS property you want to transition or animate. This property's value can be any property that you wish to animate, as long as it's an animatable property. The default value is none, which means no property transitions; likewise, if you specify a value of all, all animatable properties applied to the element transition.
The transition-duration property specifies how long the transition takes to finish. That is, the duration of time from the start of the transition to the end. The duration repeats when the element transitions back to its original state. You can specify the duration in seconds (a number followed immediately by an "s") or milliseconds ("ms"). The default is 0s.
The transition-timing-function property specifies what some refer to as the "easing function" for the transition. This property specifies to the browser the speed of the transition and how it progresses over the duration of the transition. You can specify a value as a pre-defined function, a stepping function, or a cubic Bézier curve. The default value is ease. Other pre-defined values include linear, ease-in, ease-out, and ease-in-out. For more information on stepping functions and Bézier curves, see the specification for the transition-timing-function property. For the most part, timing functions are hard to distinguish from one another unless the duration of the transition is more than a second or two.
The transition-delay property specifies the delay that occurs before the transition begins. That is, after the transition is triggered, the delay represents the time that elapses before any transition occurs. You can specify seconds or milliseconds. A negative value is valid, as this causes the transition to begin partway through its process (effectively reversing the delay).
Transition shorthand
As mentioned, you can speecify all of these properties as part of a single shorthand declaration. Thus, you can express the example from above as follows:
.example {     transition: background-color 2s ease-in 1s; }
The order of the time-related values is important. The first time value always represents duration, so if you want to include a delay, you must first define a duration.
Multiple transitions
The transition-property long-hand syntax discussed above allows you to declare multiple transitions by comma-separating the properties you want to transition. In turn, the other long-hand values allow comma-separated values, which correspond to the transition-property values.
The shorthand syntax, however, makes it even easier to declare transitions on multiple properties at once. You do this by comma-separating the declarations, as follows:
.example {     transition:  background-color  2s ease-in 1s,      width  2s ease-in-out,      height 3s ease-out; }
You can put the multiple properties on one line if you want, or, for better readability, put each transition declaration on a separate line, as I've done above.

Triggering a transition

Now that you have a good grasp of the syntax for CSS3 transitions, what about actually triggering the transitions? The example described above defines various aspects of the transition, but does not specify when or how to trigger the transition. So as it stands, nothing would happen with the code alone.
The most common method developers use to trigger a transition is through using the :hover pseudo-class.  Thus, with the addition of the :hover trigger, the code might look like the following:
.example {     background-color: green;     transition: background-color  2s ease-in 1s; } .example:hover {     background-color: blue }
With this code, if a user hovers over the element, the background color animates from green to blue over a two-second duration, after a one-second initial delay.

Transitions triggered by events other than the :hover trigger

In reality, triggering the transition isn't so much about the trigger itself (in the case above, the trigger being :hover). What actually causes the transition to occur is the change of state for the element.
For the example above, the change of state is the change from a green background color to a blue background color. It just so happens that the change of state occurs as a result of the :hover event.
To illustrate the irrelevancy of the actual event that triggers the transition, and to emphasize the importance of the state change, here are a number of other ways to trigger a transition.
Using :active
The :active pseudo-class represents the state that occurs when a user clicks an element and holds the mouse button. The code is as follows:
.example {     width: 200px;     height: 200px;     transition: width  2s ease-in; } .example:active {     width: 400px; }
In this example, the transition of the width property occurs while the user clicks on and holds the click in place on an element, thus maintaining the element's "active" state.
Using :focus
The :focus pseudo-class usually occurs when an element receives keyboard focus. The code is as follows:
input {     width: 200px;     transition: width 2s ease-in; } input:focus {     width: 250px; }
In this case, the transition occurs on a form input element and transitions the width of the form input element when the field receives focus.
As a side point here, where possible, it's probably a good idea to add :focus to your selector stack when applying a transition for the :hover pseudo-class. This way, you'll be enriching the experience for mouse users and keyboard users.
Using :checked
The :checked pseudo-class occurs when a checkbox or radio button is in the selected state. To trigger a transition when this occurs, you would do something like the following:
input[type="checkbox"] {     transition: width 1s ease; } input[type="checkbox"]:checked {     width: 30px; }
In this case, although the width change will not actually make any visible difference to the checkbox itself, it appears recessed, as the space the form field holds will increase.
Using media queries
Another way you can trigger a state change for an element is by means of CSS3 media queries. If you've studied media queries at all, then you know that they allow you to change the styles applied to elements depending on certain factors like device width and orientation. A media query transition might look as follows:
.example {     width: 200px;     height: 200px;     transition: width 2s ease, height 2s ease; } @media only screen and (max-width : 960px) {     .example {         width: 100px;         height: 100px;     } }
In this example, the element has a width and height of 200px by 200px. If, however, the user resizes their window to be 960px or less, the element transitions to a reduced size of 100px by 100px. The transition occurs when the window passes the 960px threshold.
Of course, if the user's window size is 960px or lower on page load, the browser applies the styles in that section, but the transition does not occur because there would then be no state change.
As you can see from the examples above, you can trigger transitions basically through any event that changes an element's CSS in some way. So as long as the properties that change are animatable, the transition will occur.

Transitions triggered by JavaScript

You may have figured something out at this point: If you can trigger a transition with a CSS-based state change, then certainly you can do this with JavaScript.
In the example below, the transition occurs the same as it does when using the pure CSS examples—that is, as a result of a CSS state change, however, this time JavaScript triggers the transition.
The following is an example that uses a simple jQuery script to toggle a class name on an element:
$(function() {     $("#button").click(function() {         $(".box").toggleClass("style-change");     }); });
Assuming you have an element with box class in your markup and a button element id, this script causes the style-change class to toggle on the box class each time a user clicks the #button element.
This on its own won't do anything, though. You can add a transition to the style-change class, so that each time the style-change class is added or removed, the width and height  transitions to and from the values specified in the two declaration blocks, as follows:
.box  {     width: 200px;     height: 200px;     transition: width 2s ease, height 2s ease; } .style-change {     width: 300px;     height: 300px; }
Again, this code snippet emphasizes the point that transitions occur as a result of style changes, and you can trigger those changes in any number of ways including through JavaScript.
This is an important point to keep in mind when considering whether to use CSS transitions in place of JavaScript. I find that a good rule to keep in mind is that events should generally occur with JavaScript, and simple animations or transitions should occur using CSS. Of course, this is just a general guideline, and may not always be the best choice, depending on the circumstances.

Transition tricks and techniques

Now that you have a good understanding of the syntax for transitions and how you might use them, I'll go over a few little tricks that might come in handy in one of your projects.
Different transitions for on and off states
At this point, after testing some of the examples, you've probably noticed that the transitions generally occur leading up to the "on" state as well as leading back to the original "off" state. But there's a way to define different transitions for on and off states.
In the following code example, the transition of the background color occurs on both the on and off states:
.example {     width: 100px;     height: 100px;     background-color: blue;     transition: background-color  2s linear; } .example:hover {     background-color: green; }
Let's change the duration and timing function for the off state, as follows:
.example {     width: 100px;     height: 100px;     background-color: blue;     transition: background-color  1s ease-out; } .example:hover {     background-color: green;     transition: background-color  2s linear; }
In this code, I moved the original transition declaration to the :hover state, and I added a new line to the styles applied to the element before triggering :hover. Now the "on" transition takes two seconds (specified as 2s linear), and the "off" transition takes one second (specified as 1s ease-out).
The idea is that you have specified to the browser that when the element transitions from green to blue, the element transitions using 1s ease-out, but when the element transitions from blue to green, the element transitions using 2s linear.
This could help the usability of various UI elements. For example, if you're transitioning something over three or four seconds (which is a bit lengthy), you can return the element back to its normal "off" state over a shorter duration.
You can also check out an article on my website called, Mimic 'onmouseout' with CSS3 Transitions, which discusses this concept.
Virtually infinite delays
Another trick involving transitions is the use of infinite delays to mimic a permanent state change without the need for JavaScript.
The code is as follows:
.example {     width: 100px;     height: 100px;     background-color: blue;     transition: width 0s ease-out 999999s,                 height 0s ease-out 999999s; } .example:active {     width: 200px;     height: 200px;     transition: width 2s,                 height 2s; }
In this case, I use the :active state to change the width and height of the element. The transition that occurs for the on state occurs over a duration of 2 seconds. The element’s transition back to the original dimensions (100x100), however, has a delay of 999999s and a 0s duration. The duration, however, is irrelevant because basically the delay is infinite in web page time, being equivalent to about 12 days!
This means the off state (or the original state of the element before triggering the :active state) never occurs—unless the user waits 12 days. Thus, the result is that the :active state becomes permanent and creates the illusion that the element's styles changed using JavaScript.
Hat tip to Joel Besada for describing this technique in his blog post, Maintaining CSS Style States using “Infinite” Transition Delays.
Smoother transitions with hardware acceleration
There are times when CSS-based animations are not as smooth as you'd like them to be. Sometimes animated elements leave behind a "trail" where an animation occurred. This is usually a problem on WebKit and in particular has been noted on iOS-based devices. You can improve the performance of transitions in WebKit by enabling hardware acceleration. The following is a simple transition using a -webkit- prefix:
.example {     width: 200px;     height: 200px;     -webkit-transition: width 2s ease,       height 2s ease; } .example:hover {     width: 300px;     height: 300px; }
This example transitions the width and height of the element from 200x200 to 300x300. In the Chrome browser, this results in a trail that lags behind, as shown in Figure 1.
Figure 1. Lagging trail left behind in Chrome during a transition
Figure 1. Lagging trail left behind in Chrome during a transition
To fix this problem, you must enable hardware acceleration by adding a single line of CSS. The following shows the corrected code:
.example {     width: 200px;     height: 200px;     -webkit-transition: width 2s ease,       height 2s ease;     -webkit-transform: translateZ(0); } .example:hover {     width: 300px;     height: 300px; }
The new line adds the translateZ() function to the transform property. The function itself is normally used to "translate" or position an element on the z-axis (in 3-D space), but a zero value prevents any actual repositioning. The benefit of this function is that the element transitions with hardware acceleration, which smooths the transition and eliminates the trail or streak, but the value of zero does not reposition the element.
This could also come in handy when you notice transitions causing elements to blink or flash before they start to animate. For more on hardware acceleration, see the section, Visual Fidelity++with HTML5: Hardware Acceleration in the article, Improving the Performance of Your HTML5 App, on HTML5 Rocks website.

Browser support and vendor prefixes

Browser support for CSS3 transitions, all things considered, is very good. All browsers now support transitions with prefixes or without. The upcoming browsers, Internet Explorer 10, Firefox 16, and Opera 12.5, all support transitions without prefixes, while older browser versions such as Chrome and Safari support transitions using their respective vendor prefixes. The only browsers that are in significant use that don't support transitions are Internet Explorer 6-9 and Firefox 3.6. For a detailed breakdown on support and prefix use, see the reference, When can I use... Compatibility tables for support of HTML5, CSS3, SVG and more in desktop and mobile browsers.

Where to go from here

I hope this article has helped you understand CSS3 transitions and the nuances of the syntax, along with some useful tips and techniques.
For further reading on CSS3 transitions, check out any of the following resources: