Command Palette

Search for a command to run...

Hectal
Shots in this scene
SHOT 3.1Beginner ~21 min · shot 1 of 6

Your First Transition

In one line

A transition tells the browser to take time over a style change instead of jumping. The browser starts one when a style changes on a frame, and it reads the transition settings from the new style, so the rule must sit on the right selector.

0/6 · 0%

Think of it like this

A light switch changes a room from dark to bright in one instant. A dimmer knob changes it gradually. A CSS transition is a dimmer fitted to a property. You still flip the state (dark, then bright), but you have told the browser how long to take getting there.

Words you'll meet

New words in this topic, in plain English. Come back here whenever one feels fuzzy.

transition
An instruction to take time over a change of one or more CSS properties, instead of changing in a single frame.
style change
A property's computed value being different from the value it had after the previous frame, whatever caused it (hover, class, script, media query).
CSSTransition
The browser's object for one running transition of one property on one element. It is what you see as a track on the Motion Timeline.
shorthand
One property that sets several at once. transition: opacity 200ms ease-out sets the property, duration and timing function together.

Step by step

01Read the settings

Run "Your first transition". The console prints the four longhand values the browser has for the pill: property: background-color, color, duration 0.2s, timing ease-out, delay 0s. It also prints tracks at load: 0: nothing animates until something changes.

02Cause a change and find the tracks

Press Toggle the .hot class. Two tracks appear, transition · background-color and transition · color, each 200 ms long. One change of class made two transitions, one per property.

03Slow it down and step through

Press 0.1× and toggle again. Click a track to see its graph: ease-out rises quickly and flattens. At 100 ms (half the time) the background is already about two thirds of the way to orange.

04Run the audit

Open "When does a transition start?". Its console counts the tracks after six different changes. Only two of the six make a transition. The text under that example explains each line.

Try it yourself

  1. 1

    Animate only the background

    In "Your first transition", change transition-property: background-color, color; to transition-property: background-color;. Press Toggle the .hot class: only one track appears, and the text is already white while the background is still white. Frozen 100 ms in, the background is rgb(255, 154, 111) and the text is rgb(255, 255, 255): pale text on a pale orange background. With both properties listed, at the same moment the text is rgb(183, 183, 185), a grey in between.

  2. 2

    Make the duration zero

    Change transition-duration: 200ms; to transition-duration: 0s; and toggle. No track appears and the colours change in one frame: the timeline stays empty ((no animations) in the tool). A transition with no duration is never created.

Code & diagrams

Your first transition

The pill changes colour when you hover it or press the button. Look at the console for the four settings, then pause and step through a change on the timeline.

Press Run to see the page.
00:00.000
animations
0.00s0.10s0.20s0.30s0.40s0.50s0.60s0.70s0.80s0.90s

Nothing is moving yet. Hover, click or scroll the page: every animation it starts shows up here as a track.

frames

Console

Nothing logged yet.

Expected console output

property: background-color, color
duration: 0.2s
timing:   ease-out
delay:    0s
tracks at load: 0
When does a transition start?

Press the three buttons to see each box move (A both ways, B only one way, C not at all). The console audit builds fresh boxes and counts the tracks the browser makes. Every line is a rule from the text above.

Press Run to see the page.
00:00.000
animations
0.00s0.10s0.20s0.30s0.40s0.50s0.60s0.70s0.80s0.90s

Nothing is moving yet. Hover, click or scroll the page: every animation it starts shows up here as a track.

frames

Console

Nothing logged yet.

Expected console output

A, class added:                 1
B, class added:                 1
B, class removed:               0
C, 0ms, class added:            0
A, inserted already .on:        0
A, added and removed one frame: 0
Feel itHow long should a hover take?

Hover each button. Which one feels like it answers your pointer?

A A

Press Run to see the page.

B B

Press Run to see the page.
Play both, then choose:

Break it on purpose

Errors are the best teachers. Make each change, read the error, guess what went wrong, then reveal the answer.

Break #1

Put the transition on the hover rule only

In "Your first transition", delete the four transition-* lines from .pill, and add transition: background-color 200ms ease-out, color 200ms ease-out; to the .pill:hover, .pill.hot rule instead.

terminal
$ Press Toggle the .hot class twice, with the second press 300 ms after the first
── what you'll see ──
The colour fades to orange over 200 ms, then snaps straight back to white on the second press. On the timeline the second press makes no track, and the background reads rgb(255, 255, 255) at once.
Measured: the tracks from the first change end as idle, and nothing replaces them.

Break #2

Leave out a unit

Replace the four longhands with transition: background-color 200, color 200;.

terminal
$ Run the example and read the console
── what you'll see ──
property: all
duration: 0s
timing: ease
delay: 0s
Captured from a real run: the whole shorthand was thrown away and the defaults came back. No error appears anywhere.

Myth vs fact

Myth

A transition plays whenever a property changes.

Fact

It plays when a property changes on a frame the browser has seen before, and the new style declares a duration above zero. Elements that appear in their final style, and changes that undo themselves inside one frame, do not animate.

Myth

Put the transition on :hover so it only runs on hover.

Fact

It then runs in one direction only. Put it on the normal rule, so it describes the element, and let the state rules change values.

Pro corner

Extra depth for experienced readers. New to this? Skip it for now and come back later.

  • ▸

    The browser decides at style recalculation, once per frame, by comparing the before-change and after-change computed styles. That is why void el.offsetWidth (forcing a style recalculation) between two changes in the same script makes them two separate changes, and why two toggles without it can cancel to nothing. Phase 6 covers the cost of forcing it.

  • ▸

    A transition of transform or opacity can run on the compositor thread (Topic 6.1). What a colour costs depends on the property: in Chromium 153 background-color is composited, while color and box-shadow repaint. Read the cost colour on the timeline instead of guessing (Topic 6.2).

Remember this

  1. 1

    The problem this solves: without a transition, a hover colour, a pressed button or a focused field changes in a single frame. The eye is poor at noticing instant changes, and a hard cut feels abrupt. A transition spreads the change over 100 to 300 milliseconds, long enough to see, short enough to stay out of the way. The CSS course (Topic 10.1) showed the syntax; this topic looks at what the browser really does.

  2. 2

    Four properties and a shorthand. transition-property names what to animate (background-color, color). transition-duration says how long (200ms). transition-timing-function is the curve (ease-out; Phase 5 covers curves). transition-delay waits before starting. The shorthand transition: background-color 200ms ease-out sets them together. In the shorthand the first time value is the duration and the second is the delay, so opacity 200ms 50ms waits 50 ms.

  3. 3

    The defaults animate nothing. The initial value of transition is all 0s ease 0s: every property, zero duration. A zero duration means the change is instant, so with no transition rule you never get one. You always have to set a duration. (The timeline shows no track at all for a 0 s transition: the browser does not even create one.)

  4. 4

    A transition starts on a style change. The browser computes every element's style once per frame. If an element's computed value for a property differs from the value it had after the previous frame, and the new style has a transition for that property with a duration above zero, the browser creates a CSSTransition object, one per changed property. It appears on the timeline as transition · background-color. What caused the change does not matter: :hover, :focus, :active, a class added by JavaScript, a media query that starts to match, or a script writing style.opacity.

  5. 5

    Which style supplies the settings: the new one. The browser reads the transition values from the style the element has after the change. So a transition written on the element's normal rule (.pill { transition: … }) plays in both directions, because the normal rule applies before and after. A transition written only on .pill:hover plays when you hover in. When you hover out, the hover rule stops applying, the new style has no transition, and the colour snaps back at once. This is the most common transition bug, and the second example below shows it.

  6. 6

    When no transition starts. There is no change to animate when an element first appears already in its final style (nothing came before it). Two changes inside the same frame that return to where they began count as no change at all, because the browser only compares the style at the end of the frame with the style at the end of the last one. A duration of zero and an invalid declaration also give nothing: transition: color 200 (no unit) is thrown away whole, and the element keeps all 0s ease 0s.

Explain it without notes

01

Why does a transition written only on :hover play when you hover in but not when you hover out?

02

A developer says: my transition does not run on page load, so it is broken. What really happens?

03

What is the value of transition when nobody wrote one, and what does it mean for animating?

Practice

01

Write the CSS for a .badge that fades its background from grey to orange over 160 ms with ease-out when it gets the class .new, and back again when the class is removed.

02

A link a.more changes colour on hover, but the colour snaps back when the pointer leaves. Find the bug in a.more:hover { color: #ff6b2c; transition: color 200ms; } and fix it.

Done when you can

  • You can name the four transition properties and what the shorthand's two time values mean

  • You can explain why the transition goes on the base rule

  • You can say when the browser does not create a transition (zero duration, first style, a change undone in one frame)

  • You can find the tracks of a transition on the timeline and read its duration and easing