Using CSS transitions
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
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, 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!
: 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.