The Definitive Guide to CSS Transitions

Share this article

Back in the golden days of the web, we had a little thing called Flash to help us make the web a dynamic, fun, interactive place. But, Flash is being used less and less. Of course, in certain environments it can still be put to amazing use, but in today’s web environment you need CSS to get the job done. One of the easiest ways to give your site a near-instant facelift is to bring CSS3 transitions to the table (pun intended). As users interact with various elements on your page, transitions allow for a delayed response that is far more natural and engaging than a jarring, instant response. Case in point, hover over these two boxes and tell me which is more interesting to you. Drop this into an HTML document and check it out: [sourcecode language=”html”] <html> <head> <style> #box-static {width:250px; height:170px; background-color:#999; background-color:#999; float:left; margin:10px;} #box-static:hover {background-color:#333;} #box-dynamic {width:250px; height:170px; background-color:#999; background-color:#999; float:left; margin:10px; transition:all 1s;} #box-dynamic:hover {background-color:#333;} </style> </head> <body> <div id=”box-container” style=”width:600px;height:200px;display:block;”> <div id=”box-static”></div><div id=”box-dynamic”></div> </div> </body> </html> [/sourcecode] Yeah, I know gray boxes aren’t all that exciting, but the point is that the transitions on the box to the right are more interesting and give the design a more polished feel.

Pseudo-Classes for CSS Transitions

The key to making CSS transitions work is through the use of pseudo-classes. You’ve seen these before, even if you didn’t know what they were called. The most common example is probably the a:hover pseudo-class. [sourcecode language=”css”] a { color:#CCC; background-color:#333; } a:hover { color:#333; background-color:#CCC; } [/sourcecode] Here we have the CSS element for a link and the pseudo-class “hover” for when the mouse is over the link. Pseudo-classes are subsets of a class. They take on the parent CSS automagically and apply new or different CSS upon interacting. Some other important pseudo-classes you need to know for CSS transitions include:
  • hover: obviously.
  • active: when an element gets clicked
  • focus: for tab-based selection (accessibility and forms)
  • target: for matching an on-page ID with a link target
I won’t address the target pseudo-class in this article because it’s rare and is still buggy across browsers. But hover, active, and focus are fully functional (IE10+) and easy to implement.

Introducing CSS Transitions

With all that background out of the way, we can have a more thorough discussion of CSS transitions. They are simply a CSS property that allows you to make the differences between two different CSS elements to change slowly instead of instantly. When you hover your mouse over a button that has a pseudo-class of hover with different color of text and background, the button immediately changes. Transitions allow you to make the change occur more slowly, giving your designs a far more interactive feel. You can use transitions on just about any CSS element using pseudo-classes: divs, paragraphs, spans, tables and sub-elements of tables, images. Just apply the appropriate pseudo-class and define the CSS change. I stick with background-color for the most part as it creates an interesting effect.

Properties of the CSS Transition

To be thorough, the above example is simply consolidating several CSS Transition properties:
  • Transition-property: the CSS you want to target for the transition, like color, background-color, width, height, etc
  • Transition-duration: how long in seconds or milliseconds you want the transition to take.
    • For seconds, use an ‘s’ like 2s
    • for milliseconds, use ‘ms’ like 2000ms
  • Transition-timing-function: how the transition merges, meaning that you can adjust to have an eased transition, stepped, or linear. Default is ease, which works for 99% of what I need, but here are the primary attributes:
    • ease-in starts the transition slowly and finishes at full speed
    • ease-out starts the transition at full speedand finishes slowly
    • ease-in-out starts slowly, gets fastest in the middle of the transition, and finishes slowly.
    • ease is nearly identical to ease-in-out except it’s a little less dramatic towards the middle of the transition
  • Transition-delay: also in seconds or milliseconds, defines an amount of time to delay before starting the transition.
Or, you can consolidate all these into a single transition, just keep them in the following order: [sourcecode language=”text”] transition: property duration timing-function delay; [/sourcecode] A complete example would look like this: [sourcecode language=”css”] a { color:#CCC; background-color:#333; transition:color 1s ease-in-out 500ms, background-color 1s ease-in-out 500ms; -webkit-transition:color 1s ease-in-out 500ms, background-color 1s ease-in-out 500ms; } a:hover { color:#333; background-color:#CCC; } [/sourcecode] Notice that you will need to use -webkit-transition to make these work in the vast majority of browsers. In pseudo-code, this would read something like: transition the color of the link, make the transition take 1 second to complete, gently ease in and out of the transition, and delay for half a second (500ms) before making the transition. You can use a comma-delimited list with the transition to cover all the target properties you want. I prefer to consolidate my transitions into the single CSS attribute, but if you had some very specific transitions you wanted to craft, you may want to break each down.

Where to Place Transitions

I wondered for awhile if I should place the transition in the parent or the child. After all, the following two examples have the same exact effect: [sourcecode language=”css”] a { color:#CCC; background-color:#333; transition:color 1s ease-in-out 500ms, background-color 1s ease-in-out 500ms; -webkit-transition:color 1s ease-in-out 500ms, background-color 1s ease-in-out 500ms; } a:hover { color:#333; background-color:#CCC; } [/sourcecode] –OR– [sourcecode language=”css”] a { color:#CCC; background-color:#333; } a:hover { color:#333; background-color:#CCC; transition:color 1s ease-in-out 500ms, background-color 1s ease-in-out 500ms; -webkit-transition:color 1s ease-in-out 500ms, background-color 1s ease-in-out 500ms; } [/sourcecode] But here’s what I’ve found, I prefer to put the transition in the parent so that all other child elements get the transition. If you want separate effects based upon the situation, you can always provide a different transition specific to that element. But I find that to be extremely rare. 99% of the time I want a consistent transition effect, so I put the transition in the parent element.

Beyond :hover and Links

Two other really important pseudo-classes need to be discussed for this to be a thorough guide: active and focus. Active is when an items is actually clicked and can have its own separate transitions. While not critical from a design standpoint, this can add a whole other layer of interactivity to your designs. Focus is for tab-based browsing. I use it on forms and navigation elements primarily, but should be considered any time you need to make your site more accessible. My focus typically mirrors my hover, simply because they’re about the same thing from a functionality standpoint. This is where delaying the effect by 250-500 milliseconds can be useful so that you users aren’t tabbing through what may look like a Christmas tree as every tabbed element goes through a transition.

Working Sample

Let’s pull all these concepts together into a complete working sample. I like using transitions on menu items: [sourcecode language=”html”] <html> <head> <style> /* make the li inline for horizontal menu */ #menu li { display:inline; font-size:18px; margin: 3px 8px 3px 8px; } /* initial definitions */ #menu a { color:#333; border-bottom: #333 2px solid; background-color:#fff; padding:5px; text-decoration:none; transition:color 1s ease-out 250ms, background-color 1s ease-out 250ms; -webkit-transition:color 1s ease-out 250ms, background-color 1s ease-out 250ms; } #menu a:hover { color:#fff; background-color:#666; } #menu a:focus { color:#fff; background-color:#666; } /* note how I made the transition delay 0ms */ #menu a:active { color:#333; background-color:#666; transition: 1s 0ms; } </style> </head> <body> <div id=”menu”> <ul> <li><a href=”#” tabindex=”1″>Nav Text 1</a></li> <li><a href=”#” tabindex=”2″>Nav Text 2</a></li> <li><a href=”#” tabindex=”3″>Nav Text 3</a></li> <li><a href=”#” tabindex=”4″>Nav Text 4</a></li> <li><a href=”#” tabindex=”5″>Nav Text 5</a></li> </ul> </div> </body> </html> [/sourcecode] Do you rely on CSS3 transitions within your designs?. Would you use it for essential functionality, or just an added layer of polish for those who support it with modern browsers?

Frequently Asked Questions about CSS Transitions

What is the difference between CSS transitions and animations?

CSS transitions and animations are both powerful tools for creating smooth, engaging web designs. However, they serve different purposes. Transitions are used to change property values smoothly over a specified duration, typically in response to user interaction such as hover, focus, or active states. On the other hand, animations are more complex and can control the intermediate steps in a sequence of changing styles, allowing for more intricate effects.

How can I control the speed of a CSS transition?

The speed of a CSS transition is controlled by the ‘transition-duration’ property. This property defines the length of time that a transition should take to complete. You can specify this duration in seconds (s) or milliseconds (ms). For example, ‘transition-duration: 2s’ would make the transition last for 2 seconds.

Can I apply multiple transitions to the same element?

Yes, you can apply multiple transitions to the same element. To do this, you simply separate each transition property with a comma. For example, ‘transition: width 2s, height 2s’ would apply a 2-second transition to both the width and height of the element.

What happens if I don’t specify a transition duration?

If you don’t specify a transition duration, the transition will not occur. This is because the default value for ‘transition-duration’ is 0s, which means the transition happens instantly. To ensure a smooth transition, always include the ‘transition-duration’ property.

Can I use CSS transitions with all CSS properties?

Not all CSS properties can be transitioned. Only properties that have an identifiable halfway point can be transitioned. These include most of the properties that you would typically want to animate, such as ‘width’, ‘height’, ‘opacity’, ‘color’, and ‘font-size’.

How can I make a transition happen only when a certain condition is met?

CSS transitions are typically triggered by a change in state, such as when a user hovers over an element. You can specify this state change using pseudo-classes like ‘:hover’, ‘:active’, or ‘:focus’. For example, ‘a:hover {transition: color 1s}’ would transition the color of a link over 1 second when the user hovers over it.

What is the ‘transition-timing-function’ property?

The ‘transition-timing-function’ property allows you to control the speed curve of the transition. This means you can specify how the intermediate property keyframes are calculated. The default value is ‘ease’, which starts slow, speeds up in the middle, and then slows down at the end. Other values include ‘linear’, ‘ease-in’, ‘ease-out’, and ‘ease-in-out’.

Can I use CSS transitions to create a slide-in effect?

Yes, you can use CSS transitions to create a slide-in effect. This can be achieved by transitioning the ‘left’, ‘right’, ‘top’, or ‘bottom’ property of an absolutely positioned element. For example, ‘transition: left 2s’ would create a slide-in effect from the left over 2 seconds.

How can I delay a CSS transition?

You can delay a CSS transition using the ‘transition-delay’ property. This property specifies how long to wait from the time a property is changed until the transition begins. Like ‘transition-duration’, this value can be specified in seconds (s) or milliseconds (ms).

Are CSS transitions supported in all browsers?

CSS transitions are widely supported in all modern browsers, including Chrome, Firefox, Safari, and Edge. However, for older browsers that do not support CSS transitions, it’s important to ensure that your design still works without the transition effect.

Justyn HornorJustyn Hornor
View Author

When he's not being a complete goofball, “they” drag Justyn into the office where he pretends to be a Senior Editor and Content Engineer at Creative Content Experts — a content marketing firm out of NW Arkansas. He has 10+ years’ experience in technical writing and geek-related fields. He loves WordPress, coffee, and peanut butter a little too much.

CSScss transitions
Share this article
Read Next
Get the freshest news and resources for developers, designers and digital creators in your inbox each week