Animation

We use animated transitions to add delight and to signal the app’s response: for every action, there’s a reaction.

We use animations to nudge the user to take a specific action, or just invite them to tinker and explore. For example, animations can:

  • Hint that an component is interactive
  • Show a transition between views
  • Indicate that there’s something happening behind the scenes
  • Help give immediate feedback and signal the app’s response: for every action, there’s a reaction

Best practices for animation

  • Be intentional. When designing animated elements, we want to be helpful and fun, not distracting. Think of it like wasabi: a little can go a long way.
  • Use real-world metaphors to make the animation feel intuitive. For example, a dropdown opens downward, as if it was subject to gravity.
  • Use subtle motion—not too fast, not too slow.
  • If you're using several animated elements, make sure they feel coordinated.
  • Avoid animations when the message is serious, or when delivering bad news. It can strike the wrong tone and hurt comprehension.

Animation for components

We want our animations to feel natural. Here are some concepts we use when designing animation for components:

Convey depth

We use depth to make our components friendly and proactive. Many of our components rise to greet the user’s cursor when hovered upon.

{% toggleText('button-example') %}
.button {
    // non-animation styles are omitted
    @include transition(all $transition-speed-faster);
    &.primary {
        &:hover {
            @include transform(translateY(+-$button-depth));
        }
        &:active {
            @include transform(translateY(0));
        }
    }
}

Use natural directions

If an element has natural direction, like left and right, we animate towards that direction.

Jul 1 - Jul 31, 2015
{% toggleText('direction-example') %}
.chart-control-range {
    // non-animation styles are omitted
    svg {
        @include transition(all $transition-speed-faster);
    }
    .arrow-navigation {
        &:hover {
            svg {
                &.arrow-right {
                    @include transform(translateX(2px));
                }
                &.arrow-left {
                    @include transform(translateX(-2px));
                }
            }
        }
    }
}

Mimic a movement

We use a head-shaking motion to indicate an action is not allowed.

{% toggleText('shake-example') %}

@include keyframes(buttonShake) {
    0% {
        @include transform(translateX(0px));
    }
    10% {
        @include transform(translateX(-5px));
    }
    30% {
        @include transform(translateX(5px));
    }
    50% {
        @include transform(translateX(-5px));
    }
    70% {
        @include transform(translateX(5px));
    }
    90% {
        @include transform(translateX(-5px));
    }
    100% {
        @include transform(translateX(0));
    }
}

.button {
    // non-animation styles are omitted
    .disabled {
        &:focus {
            @include animation(buttonShake $transition-speed);
        }
    }
}

Transitions between views

We use transitions to create a better user experience when users go from one view to another. Here are some principles to consider when designing transitions:

Focus on what’s important

In this example, the chart is animated in to help guide the user's attention.

Indicates that something’s happening

These animated indicators tell the users their data is loading.

Establish a sense of hierarchy

In this example, we fade out the main content when the modal is shown, indicating an action is required.

Speed reference

Use these timing variables to help keep a consistent feel across the interface.

Sass variable Description Default
$transition-speed-faster A faster speed, best when animated object is going a short distance or isn’t making extreme movements. 0.2s
$transition-speed Base motion speed. Use for buttons, dialogs. 0.4s
$transition-speed-slower A slower, more deliberate motion, good for motion across larger distances. 0.8s

Motion reference

Sass variable Graph Default
$bounce cubic-bezier(.5,-0.35,.15,1.25)
$ease cubic-bezier(.45,.45,0,1)