Learning path · Level 2 · Tutorial 7

Create Accessible CSS Transitions

Add restrained transitions to interface state changes and provide a reduced-motion alternative that preserves immediate, usable feedback.

  • Level: Beginner
  • Duration: 13 min
  • 7 steps
Start tutorial Back to the path
Create Accessible CSS Transitions

What you will go through

  1. Understand What a Transition Changes Learn what a CSS transition adds to an existing interface state change. 1 min
  2. Set and Scope a Short Transition Add a deliberately scoped background-color transition to the workshop link using longhands and equivalent shorthand. 2 min
  3. Add a Small Transform Without Shifting Layout Apply a small transform to the link label while keeping the link target and surrounding normal-flow content stable. 2 min
  4. Keep Feedback Immediate and the Target Stable Evaluate restrained motion so a control keeps immediate feedback and a stable target. 2 min
  5. Respect the Reduced-Motion Preference Add a preference-based CSS override that removes nonessential label motion while preserving immediate hover and keyboard-focus feedback. 2 min
  6. Compare Both Motion Modes Locally Verify the workshop link locally under default and reduced-motion preferences, using pointer and keyboard checks. 2 min
  7. Apply and Review Accessible Transitions Complete and verify a restrained CSS transition treatment that preserves usable feedback for pointer, keyboard, and reduced-motion preferences. 2 min

What you will learn

  • Add a short transition to deliberately selected properties during an existing hover or focus state change.
  • Use a small transform-based visual change without disrupting surrounding content or making a control difficult to use.
  • Write a prefers-reduced-motion rule that removes nonessential movement while retaining clear state feedback.
  • Compare normal and reduced-motion behavior locally and confirm that focus remains visible and controls remain usable.

Before you start

  • Style Accessible Hover, Focus, and Disabled States

Step 1 of 7

Understand What a Transition Changes

Learn what a CSS transition adds to an existing interface state change.

See the Change Over Time

A State Change Comes First

A transition changes how a supported property moves from one value to another after an existing state change begins. It does not create hover, keyboard focus, or any other interaction state.

For example, an existing hover rule can choose a darker background. Without a transition, the color changes immediately. With a transition, the browser displays in-between color values briefly before reaching that same darker background.

The interaction still works either way: the state selects the final appearance; the transition only affects the visual journey.

A Short Visual Timeline

A three-stage diagram of one link changing from its resting blue background through in-between blue shades to a darker active background.

A transition can show intermediate values between a resting value and the final value.

Separate Trigger from Motion

Same Result, Different Path

Both versions reach the same final appearance. The difference is whether the change is immediate or briefly interpolated.

A transition is useful only when the property can change smoothly. In this tutorial, background-color and transform are the supported examples. Other property changes may not produce a smooth in-between result.

A short visual transition should support feedback, not become the only way to notice that a control changed state.

Example

Compare the Two Behaviors

Immediate background change

  1. The pointer hovers over the link.
  2. The existing hover state applies the darker background.
  3. The darker background appears at once.

Short background transition

  1. The pointer hovers over the same link.
  2. The same existing hover state applies the darker background.
  3. The displayed color briefly passes through intermediate shades, then reaches the darker background.

The hover state is the trigger in both cases. Only the second path includes a transition.

Check Your Understanding

Identify the Timeline Roles

Match each observation to its role in the timeline.

Tap an item and then its matching pair.

Step 2 of 7

Set and Scope a Short Transition

Add a deliberately scoped background-color transition to the workshop link using longhands and equivalent shorthand.

Start with the workshop link

Set up the local page

Create two files in the same local folder: index.html and styles.css. Save the complete contents of both files below before opening or refreshing index.html in your browser.

The supplied CSS already defines the link’s resting, hover, and keyboard-focus states. At this point, its background-color change is immediate; you will add the transition after confirming this baseline.

index.html

Save as index.html.

html
<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>CSS Practice Workshop</title>
  <link rel="stylesheet" href="styles.css">
</head>
<body>
  <main>
    <h1 id="top">CSS Practice Workshop</h1>
    <p>
      <a class="action-link" href="#details"><span class="action-label">View session details</span></a>
    </p>

    <section>
      <h2 id="details">Session details</h2>
      <p>A 30-minute CSS practice session.</p>
      <p><a href="#top">Back to top</a></p>
    </section>
  </main>
</body>
</html>
Expected output
Rendered page after both files are saved:
- Heading: CSS Practice Workshop
- A blue link labeled “View session details”
- A Session details heading and its paragraph
- A Back to top link

Open this file only after saving `styles.css` in the same folder.

styles.css

Save as styles.css. These baseline rules provide the existing component and state feedback.

css
body {
  margin: 2rem;
  font-family: Arial, sans-serif;
  background-color: #ffffff;
}

.action-link,
.action-label {
  display: inline-block;
}

.action-link {
  padding: 0.75rem 1rem;
  color: #ffffff;
  background-color: #1e40af;
  text-decoration: none;
}

.action-link:hover,
.action-link:focus-visible {
  background-color: #1e3a8a;
  text-decoration: underline;
}

.action-link:focus-visible {
  outline: 3px solid #111827;
  outline-offset: 3px;
}
Expected output
Expected baseline behavior:
- Resting link: white text on #1e40af blue.
- Hover or keyboard focus: background changes immediately to #1e3a8a and the text is underlined.
- Keyboard focus: a 3px dark outline appears with a 3px offset.

This baseline intentionally has no transition declaration yet.

Scope the color transition

Choose one property and a short timing

Keep the hover and :focus-visible rules unchanged. Add transition longhands to the base .action-link rule, where the resting background is defined. A transition on the base selector can run when a state begins and when it ends.

150ms and 0.15s name the same duration. linear progresses at a constant rate; ease changes rate during the short interval. This example finishes with ease.

A background-color transition

A three-stage diagram shows a blue link changing through an intermediate shade before reaching a darker blue state, with symbols for selected property, short duration, and rate pattern.

The interaction state still selects its final color immediately; the explicitly selected background-color value is what interpolates.

Transition longhands

Each longhand has one job.

Use an explicit property instead of allowing every future style change to animate.
LonghandExample valuePurpose
transition-propertybackground-colorSelect only the color change
transition-duration150ms or 0.15sSet the short interval
transition-timing-functionlinear or easeChoose the rate pattern

Explicit longhands

Replace the .action-link rule in styles.css with this longhand version, then save and refresh the local page.

css
.action-link {
  padding: 0.75rem 1rem;
  color: #ffffff;
  background-color: #1e40af;
  text-decoration: none;
  transition-property: background-color;
  transition-duration: 150ms;
  transition-timing-function: ease;
}
Expected output
Expected behavior after refresh:
- Resting link: white text on #1e40af blue.
- Entering or leaving hover: the background-color changes over 150ms with ease.
- Entering or leaving keyboard focus: the background-color changes over 150ms with ease; the underline and dark focus outline remain visible immediately.

Hover and focus use the same final colors and cues as the baseline; only the background-color change now interpolates.

Write a focused shorthand

Use the equivalent shorthand

The three longhands can be written as one shorthand declaration in this order: property, duration, timing function. Replace the three transition longhands with the shorthand below. The resulting behavior is equivalent.

Finished .action-link rule

Use this finished .action-link rule in styles.css, then save and refresh the page.

css
.action-link {
  padding: 0.75rem 1rem;
  color: #ffffff;
  background-color: #1e40af;
  text-decoration: none;
  transition: background-color 150ms ease;
}
Expected output
Expected behavior after refresh:
- The resting link remains #1e40af with white text.
- On hover or keyboard focus, its background briefly eases to #1e3a8a.
- When hover or focus ends, the background briefly eases back to #1e40af.
- Underline and keyboard focus outline still appear immediately.

This replaces only the three transition longhands from the preceding version; keep the other stylesheet rules unchanged.

Tip

Keep the scope deliberate

Avoid transition: all. It could animate a property added later even when that change should stay immediate. 150ms is a restrained example, not proof that motion is comfortable for every person.

Practice the shorthand

Complete the transition

Complete the base-selector shorthand so it matches the intended scoped transition.

css
.action-link {
  padding: 0.75rem 1rem;
  color: #ffffff;
  background-color: #1e40af;
  text-decoration: none;
  transition:   ;
}

Step 3 of 7

Add a Small Transform Without Shifting Layout

Apply a small transform to the link label while keeping the link target and surrounding normal-flow content stable.

Visual change, stable layout

Move the label visually, not the link

A transform changes how an element is painted without changing the normal-flow space it occupies. Apply it only to the inner .action-label, not to the padded .action-link target.

In the active state, translate(0, -2px) draws the label 2 pixels upward. scale(1.02) draws it at 1.02 times its original size—about 2% larger. The label’s original layout footprint remains where it was.

Visual bounds versus layout space

A before-and-after diagram shows an inner label drawn slightly higher and larger while the link surface and neighboring paragraph lines stay in the same positions.

A transform changes the label's visual bounds. It does not reallocate normal-flow space or push neighboring content.

Apply a restrained transform

Add the label transform rules

In styles.css, add these rules for the existing inner label. The resting transform gives the label a predictable starting appearance. Put the transition on .action-label so it can run when the state begins and when it ends.

Keep the existing .action-link background-color transition and its hover and focus-visible feedback rules.

styles.css

Add these rules after the existing .action-link rules in styles.css, then save and refresh index.html.

css
.action-label {
  display: inline-block;
  transform: translate(0, 0) scale(1);
  transition: transform 150ms ease;
}

.action-link:hover .action-label,
.action-link:focus-visible .action-label {
  transform: translate(0, -2px) scale(1.02);
}
Expected output
On hover or focus-visible, the inner label moves upward by 2px and grows slightly. When the state ends, it returns to its resting appearance. The padded link surface and neighboring content remain stationary.

Rendered behavior after saving and refreshing the local page.

See the limited movement

The transform is deliberately limited to the inner label. The clickable link surface stays in place.

Practice the CSS

Complete the transform declarations

Complete the label rules for the established resting and active states.

css
.action-label {
  display: inline-block;
  transform: ;
  transition: ;
}

.action-link:hover .action-label,
.action-link:focus-visible .action-label {
  transform: ;
}

Predict the layout result

Check the visual effect

Which choice correctly completes the label treatment and predicts the result when the active state applies?

Step 4 of 7

Keep Feedback Immediate and the Target Stable

Evaluate restrained motion so a control keeps immediate feedback and a stable target.

Separate feedback from motion

Motion is not the interaction

A transition is optional polish, not the signal that makes a control understandable. A person should be able to notice the background-state feedback, underline, and keyboard focus as soon as the link enters a state—even if they do not perceive the label movement.

The state rules apply without delay. The background transition begins without delay but interpolates toward its final color for 150ms. The underline and focus outline do not transition, so they appear immediately.

Keep the padded link itself stationary. The small visual change belongs to its inner label, so the clickable area and its place in the page do not shift.

What stays still

Diagram of a fixed padded link and focus outline with only its inner label moving slightly upward and growing, while neighboring content remains still.

The link footprint and focus outline remain fixed; only the label's visual bounds change.

Evaluate the whole interaction

Stable-control checklist

Use this check before keeping a motion treatment.

Motion can be an enhancement only when essential feedback remains available without depending on it.
CheckPreferAvoid
Interaction targetA stationary padded linkMoving or shrinking the whole link
Visual movementA small label-only change inside the surfaceA large excursion beyond the surface
State feedbackA background transition that starts without delay; immediate underline and focus outlineDelaying state rules until movement finishes
SurroundingsNo overlap or clippingLabel covering nearby content or being cut off

Warning

Do not rely on “small” alone

A short duration and a small distance do not automatically make motion accessible. Check the complete behavior: the target must remain stable, keyboard focus must be obvious immediately, and the link must still communicate its state when movement is absent.

Choose a treatment

Choose the safer treatment

Which treatment best preserves immediate, usable feedback for the workshop link?

Repair the interaction

Repair the scoped motion

Complete this repair. The clickable box must stay in place, the visible words may receive the small visual motion, and the color, underline, and focus outline must remain clear without relying on movement.

css
.action-link {
  display: inline-block;
  padding: 0.75rem 1rem;
  color: #ffffff;
  background-color: #1e40af;
  transition: background-color 150ms ease;
}

 {
  display: inline-block;
  transform: translate(0, 0) scale(1);
  transition:  150ms ease;
}

.action-link:hover,
.action-link:focus-visible {
  background-color: #1e3a8a;
  text-decoration: underline;
}

.action-link:focus-visible {
  outline: 3px solid #111827;
  outline-offset: 3px;
}

 {
  transform: translate(0, -2px) scale(1.02);
}

Step 5 of 7

Respect the Reduced-Motion Preference

Add a preference-based CSS override that removes nonessential label motion while preserving immediate hover and keyboard-focus feedback.

Keep the feedback, remove the motion

A preference-based condition

A media query is a conditional CSS wrapper. Here, it checks the user’s reduced-motion preference; it is not a viewport or screen-size rule.

When the preference is reduce, remove this component’s nonessential interpolation and label movement. Keep the state feedback: the darker background, underline, and keyboard focus outline still appear immediately.

no-preference means that no reduced-motion preference was expressed. It does not mean unrestricted motion is appropriate.

Two motion outcomes

Side-by-side diagram: a link label moves slightly within a stable blue control in one panel, while it stays still in the other. Both panels retain an underline and visible focus outline.

Default motion can add a small label movement. Reduced motion keeps the same visible state feedback without movement.

Write the scoped override

Override both interpolation and movement

Add the override after the normal component rules in styles.css. The first selector list stops both declared transitions.

A transition controls interpolation only. If you removed only the transitions, the active transform could still make the label jump instantly. The second selector list resets the resting label and both active label states, so it overrides the hover and keyboard-focus movement too.

styles.css — reduced-motion override

Add this final section after the normal .action-link and .action-label rules.

css
@media (prefers-reduced-motion: reduce) {
  .action-link,
  .action-label {
    transition: none;
  }

  .action-label,
  .action-link:hover .action-label,
  .action-link:focus-visible .action-label {
    transform: none;
  }
}
Expected output
With reduce:
The label remains stationary.
Background changes are immediate.
The underline and focus outline remain visible.

Without reduce:
The existing short background-color and label transform transitions remain.

The visible result depends on whether the browser reports the reduced-motion preference as `reduce`.

Warning

Preserve usable states

Do not remove the existing hover or :focus-visible rules. Their background-color change, underline, and focus outline remain available; they simply happen immediately when reduced motion is requested.

Practice: cover every label state

Complete the reduced-motion override

Complete the reduced-motion media condition and the two scoped selector lists.

css
@media (prefers-reduced-motion: ) {
   {
    transition: none;
  }

   {
    transform: none;
  }
}

Step 6 of 7

Compare Both Motion Modes Locally

Verify the workshop link locally under default and reduced-motion preferences, using pointer and keyboard checks.

Prepare the local comparison

Test two preference conditions

Open your local index.html and refresh the page after saving the CSS from the previous step. Compare the same link in two preference conditions:

  • Default motion: use your operating-system setting when it does not request reduced motion, or emulate prefers-reduced-motion: no-preference in browser developer tools.
  • Reduced motion: either enable your operating-system reduced-motion setting or emulate prefers-reduced-motion: reduce in developer tools.

Developer-tool emulation affects the browser session, not your operating-system setting. When you finish, return the emulation control to its default or no-preference setting.

In each condition, test pointer hover and keyboard focus separately. Move the pointer onto and away from View session details. Then use Tab and Shift+Tab to enter and leave keyboard focus. Press Enter while the link is focused; it should navigate to Session details.

What to look for

Side-by-side diagram: default motion slightly moves the inner link label while the link surface and nearby content stay fixed; reduced motion keeps the label still while the focus outline remains visible.

Compare the label’s visual movement with the stationary link target and neighboring content.

Observe and diagnose both modes

Check behavior, not just appearance

Use this observation matrix while testing. Entering and leaving hover or focus matters: a base transition can run in both directions. Check keyboard focus independently from pointer hover, because a pointer is not required to operate the link.

Observation matrix

Record what happens in each condition.

Expected checks for the local workshop link
CheckDefault motionReduced motion
Pointer enters or leavesBrief background and label changeImmediate background change; label stays still
Keyboard focus enters or leavesBrief background and label change; outline is immediateImmediate background change; outline is immediate
State feedbackUnderline and dark focus outline remain clearUnderline and dark focus outline remain clear
Layout and targetNearby content stays put; padded link target stays stableNearby content stays put; padded link target stays stable
Enter activationNavigates to the details fragmentNavigates to the details fragment

Tip

Diagnose an unexpected result

If reduce is emulated but the default movement remains, inspect the matched CSS rules. If the reduced-motion media rule is not active, the preference may not be set to reduce or the media-query syntax may be wrong. If the media rule is active but its transition or transform declaration is crossed out, the override lost in the cascade. The reduced-motion rules should come after the normal component rules and include the active label selectors.

Record your verification

Report your local comparison

On your local page, write a short comparison report. Cover both preference conditions. State what happened when pointer hover and keyboard focus entered or left the link, whether label movement disappeared under reduced motion, whether the focus cue appeared immediately, and whether Enter activated the link in each condition. Also note any clipping, shifting neighboring content, or unstable target that you observed.

Write at least 160 characters (0/160).

Step 7 of 7

Apply and Review Accessible Transitions

Complete and verify a restrained CSS transition treatment that preserves usable feedback for pointer, keyboard, and reduced-motion preferences.

Review the intended outcomes

Review the intended result

A successful repair keeps the link’s meaning and hit area unchanged. In Default motion, the blue surface changes briefly and the inner label has a restrained visual movement. In Reduced motion, the same hover and keyboard-focus feedback remains, but the label does not move.

Use this final check: select only the properties that should transition; keep movement inside the padded link; make the underline and focus outline immediate; then remove nonessential transition and transform behavior when the reduced-motion preference requests it.

Same feedback, different motion

A comparison of a link with a subtly raised inner label under default motion and a stationary inner label under reduced motion; both retain darker background, underline, and focus outline.

Default motion: brief label movement plus state feedback. Reduced motion: immediate state feedback with no label movement.

Repair the component CSS

Complete the CSS repair

Complete the repair, then enter the matching declarations in your local styles.css. Keep the existing HTML and link behavior unchanged.

css
.action-link {
  display: inline-block;
  padding: 0.75rem 1rem;
  color: #ffffff;
  background-color: #1e40af;
  transition: ;
}

.action-label {
  display: inline-block;
  transform: translate(0, 0) scale(1);
  transition: ;
}

.action-link:hover,
.action-link:focus-visible {
  background-color: #1e3a8a;
  text-decoration: underline;
}

.action-link:hover .action-label,
.action-link:focus-visible .action-label {
  transform: translate(0, -2px) scale(1.02);
}

.action-link:focus-visible {
  outline: 3px solid #111827;
  outline-offset: 3px;
}

@media  {
  .action-link,
  .action-label {
    transition: ;
  }

  .action-label,
  .action-link:hover .action-label,
  .action-link:focus-visible .action-label {
    transform: ;
  }
}

Verify the repaired link locally

Confirm both motion modes

After completing the repair in your local styles.css, save and refresh the page. Test pointer hover and keyboard focus in Default motion. Then emulate prefers-reduced-motion: reduce in browser developer tools or use your operating-system reduced-motion setting, and test again.

In one compact report, confirm the behavior you observed for the label, background, underline, focus outline, and link navigation in both modes. Include whether nearby content stayed stationary.

Write at least 120 characters (0/120).

Finish

Summary

Reusable review

Use this decision sequence whenever you add interface motion:

  • Select a specific property instead of using a broad transition.
  • Keep movement small, nonessential, and inside a stable interaction target.
  • Keep essential feedback, including focus visibility, immediate.
  • Honor the reduced-motion preference by removing transition and active transforms.
  • Verify pointer, keyboard, Default motion, and Reduced motion behavior locally.

Tutorial complete

Congratulations! You completed: Create Accessible CSS Transitions

You completed an accessible transition treatment that preserves clear interaction feedback with or without motion.

Download the App now to have access to + 5000 free courses, exercises, certificates and lots of content without paying anything!

  • 100% free online courses from start to finish

    Thousands of online courses in video, ebooks and audiobooks.

  • More than 60 thousand free exercises

    To test your knowledge during online courses

  • Valid free Digital Certificate with QR Code

    Generated directly from your cell phone's photo gallery and sent to your email

Cursa app on the ebook screen, the video course screen and the course exercises screen, plus the course completion certificate