Read more

Using CSS transitions

Dominik Schöler
September 13, 2019Software engineer at makandra GmbH

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

Illustration UI/UX Design

UI/UX Design by makandra brand

We make sure that your target audience has the best possible experience with your digital product. You get:

  • Design tailored to your audience
  • Proven processes customized to your needs
  • An expert team of experienced designers
Read more Show archive.org snapshot

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.

Dominik Schöler
September 13, 2019Software engineer at makandra GmbH
Posted by Dominik Schöler to makandra dev (2019-09-13 16:36)