CSS transitions are a simple animation framework that is built right into browsers. No need for Javascript here. They're supported by all browsers Show archive.org snapshot .
Basic usage
Transitions are used to animate the path between to property values. For example, to let the text color fade from red to green on hover, the following SASS is used (shorthand syntax):
.element
color: red
transition: color .1s
&:hover
color: green
This tells the browser "whenever the color
of an .element
changes, let it take 1/10th of a second" and next "whenever an .element
is hovered, make its text green".
Multiple animated properties are comma-separated:
.element
color: red
opacity: .9
transition: color .1s, opacity .3s
&:hover
color: green
opacity: 1
Transition durations
The motivation of animating (transitioning) UI changes is that the UI should feel natural. In the real world, nothing is "just there", everything takes its time – even if very quick. At the same time, a transition must not make the app feel clumsy. Hover styles that transition in more than 0.2 seconds give a site the perception of laggy and slow.
Thus, finding the right transition duration for a case can be tricky. I have experimented quite a bit and found these transition durations to offer a good start:
$transition-subtle: .07s
$transition-quick: .14s
$transition-distinct: .21s
The selected duration should fit the "traveled distance": a table row that slightly changes its color on hover may use the "subtle" transition. Users will not consciously notice the transition, but running the cursor over a table still looks way smoother than without. A chevron that indicates a collapsible section should take a little more time and could use a "quick" transition to give a dynamic feel. Finally, animations that serve to underline some function like a move-to-trash can use the "distinct" duration, which users usually will notice.
90% of the transitions I add use one of these values. Of course, some larger component like a full-screen menu may define and use its own transition duration.
Techniques & more
Different transitions for back and forth
: To define a transition in one direction, and a different one in the other direction, add the "forth" transition definition to the "on" state:
.element
color: red
transition: color .1s
&:hover
color: green
transition: color .5s
Since "hover" by itself is instant, the latter transition definition will be used when the user starts hovering .element
and the transition will take longer (as defined here). When the user stops hovering, only the former transition definition is left with the element, and it will quickly fade back to red.
Other easing functions
: Transitions can be given an easing function.
The default, ease
Show archive.org snapshot
, is just fine in most of the cases. You can find a demonstration of available easing functions at <cubic-bezier.com>.
Grouping multiple properties
: If you want to animate multiple properties that share some values, you can switch to the explicit properties variant for clarity:
transition: color .1s, opacity .1s
// Same as:
transition-property: color, opacity
transition-duration: .1s
// NOT the same as:
transition: color .1s, opacity
Be careful not to mix these syntaxes up: in the shorthand format, there are no shared values. transition: color .1s, opacity
will have the color transitioned in .1s, but the opacity without duration = in an instance!
Caveats
Single property
: All transitions on an element must be defined in a single property. I.e., you cannot inherit and extend a transition setting:
.element
color: red
transition: color .1s
&.-filled
background-color: blue
transition: background-color .1s // No color transition for this element any more
&:hover
background-color: brown
This may come bite you if you're inheriting some transition from somewhere you cannot see, like a mixin. It also means you cannot simply define a color transition globally.