LearnAI ToolsCareerPractice BuildsPlayContact
Lesson 2122 min read

CSS Transition

Learn how CSS transitions create smooth changes between property values using duration, timing functions, delays, and multiple transitions.

Introduction

In the previous lesson, you learned CSS Transform and how elements can be moved, rotated, scaled, skewed, and manipulated in two-dimensional and three-dimensional space.

However, when a CSS property changes from one value to another, the browser normally applies the new value immediately.

CSS Transition allows that change to happen gradually over a specified period of time.

Element Has Initial Style
↓
State Changes
↓
Browser Detects New Value
↓
Transition Starts
↓
Intermediate Values Are Calculated
↓
Final Value Is Reached
Transitions Create Smooth Change

A transition does not define a completely separate animation sequence. It smoothly changes a property from its current value to a new value.

What is CSS Transition?

CSS Transition is a feature that allows property values to change smoothly over a specified duration instead of changing instantly.

Without Transition
.button {
background: #6c5ce7;
}
.button:hover {
background: #00b894;
}

Without a transition, the background color changes immediately when the pointer enters the button.

With Transition
.button {
background: #6c5ce7;
transition:
background 0.3s ease;
}
.button:hover {
background: #00b894;
}
Transition Concept
Without Transition
Purple ─────────────────────► Green
Instant Change
With Transition
Purple ──► Blue-Purple ──► Blue-Green ──► Green
0s 0.15s 0.3s

Why Do We Need Transitions?

Instant visual changes can feel abrupt. Transitions help interfaces communicate state changes more naturally.

Smooth Changes

Change property values gradually instead of instantly.

Better Hover Effects

Create polished interactions for buttons, links, and cards.

Visual Feedback

Help users understand that an element has changed state.

Smooth Movement

Move elements naturally between positions.

Smooth Scaling

Grow or shrink elements without sudden jumps.

Professional Interfaces

Make websites feel more responsive and refined.

Instant Change

  • Property changes immediately.
  • Can feel abrupt.
  • Movement may look like a jump.
  • State changes are less polished.

Transitioned Change

  • Property changes gradually.
  • Movement feels smoother.
  • State changes are easier to follow.
  • Interface feels more polished.

Real-World Analogy

Imagine a car moving from 0 km/h to 60 km/h.

The car does not normally jump instantly from one speed to another. It accelerates over time.

Real-World ConceptCSS Transition
Starting speedInitial property value
Target speedFinal property value
Acceleration timetransition-duration
Acceleration patterntransition-timing-function
Waiting before movingtransition-delay
What changestransition-property
Transition Analogy
Start
0 km/h
│
▼
10 km/h
│
▼
25 km/h
│
▼
45 km/h
│
▼
60 km/h
Final State
CSS
Initial Value
│
▼
Intermediate Values
│
▼
Final Value

How Transitions Work

A transition needs an initial property value and a changed property value.

Initial and Final States
.box {
width: 150px;
transition:
width 1s ease;
}
.box:hover {
width: 300px;
}
Initial Width: 150px
↓
Pointer Enters Element
↓
Target Width Becomes 300px
↓
Transition Begins
↓
Browser Calculates Intermediate Widths
↓
Final Width Reaches 300px
Intermediate Values
Time Width
0.00s 150px
0.20s 175px
0.40s 210px
0.60s 250px
0.80s 280px
1.00s 300px
The Browser Creates Intermediate Frames

You define the starting value, final value, and transition behavior. The browser calculates the values between them.

Basic Transition Syntax

Longhand Syntax
.element {
transition-property: background-color;
transition-duration: 0.3s;
transition-timing-function: ease;
transition-delay: 0s;
}
Shorthand Syntax
.element {
transition:
background-color
0.3s
ease
0s;
}
PartPurpose
transition-propertyDefines which property changes smoothly
transition-durationDefines how long the change takes
transition-timing-functionDefines the speed pattern
transition-delayDefines how long to wait before starting

Transition Properties

PropertyPurposeExample
transition-propertyProperty to animatetransform
transition-durationLength of transition0.3s
transition-timing-functionSpeed curveease
transition-delayWaiting time0.2s
transitionShorthand for all transition valuestransform 0.3s ease

transition-property

The transition-property property defines which CSS property should change smoothly.

Transition Background
.button {
transition-property:
background-color;
}
Transition Transform
.card {
transition-property:
transform;
}
Transition Opacity
.image {
transition-property:
opacity;
}
ValueMeaning
noneNo property transitions
allAll transitionable changed properties
Property nameOnly the named property
Multiple namesSeveral comma-separated properties

Example 1: Background Color

HTML
<button class="color-button">
Hover Me
</button>
CSS
.color-button {
padding: 14px 28px;
border: none;
background-color: #6c5ce7;
color: white;
border-radius: 8px;
transition-property:
background-color;
transition-duration:
0.5s;
}
.color-button:hover {
background-color: #00b894;
}
Live Preview

Multiple Transition Properties

Several properties can be transitioned by separating their names with commas.

Multiple Properties
.card {
transition-property:
background-color,
color,
transform;
transition-duration:
0.3s;
}

When the state changes, only the listed properties transition smoothly.

The all Keyword

The all keyword tells the browser to transition every changed property that can be animated.

Transition All Properties
.card {
transition-property: all;
transition-duration: 0.3s;
}
Use all Carefully

The all keyword is convenient, but explicitly listing the properties is often clearer and prevents unexpected properties from transitioning.

transition-duration

The transition-duration property defines how long a transition takes to complete.

Fast Transition
.button {
transition-duration: 0.2s;
}
Slow Transition
.button {
transition-duration: 2s;
}
DurationGeneral Feeling
0sInstant change
0.1s - 0.2sVery fast
0.2s - 0.4sCommon interface speed
0.5s - 1sNoticeably slow
More than 1sUsually dramatic or demonstrative
Default Duration Is 0s

A transition will not appear smooth unless a duration greater than zero is provided.

Time Units

UnitMeaningExample
sSeconds0.5s
msMilliseconds500ms
Equivalent Durations
.one {
transition-duration: 0.5s;
}
.two {
transition-duration: 500ms;
}
1000 Milliseconds Equals 1 Second

Both seconds and milliseconds are valid. Use the format that is easiest to read consistently in your project.

Example 2: Different Durations

HTML
<div class="duration-demo fast">
Fast
</div>
<div class="duration-demo medium">
Medium
</div>
<div class="duration-demo slow">
Slow
</div>
CSS
.duration-demo {
width: 120px;
padding: 16px;
margin-bottom: 12px;
background: #6c5ce7;
color: white;
border-radius: 8px;
transition-property:
width;
}
.duration-demo:hover {
width: 300px;
}
.fast {
transition-duration: 0.2s;
}
.medium {
transition-duration: 0.7s;
}
.slow {
transition-duration: 2s;
}
Live Preview

transition-timing-function

The transition-timing-function property controls how the speed of a transition changes during its duration.

Timing Function
.box {
transition-timing-function:
ease-in-out;
}
ValueBehavior
easeSlow start, fast middle, slow end
linearConstant speed
ease-inSlow start
ease-outSlow end
ease-in-outSlow start and slow end
cubic-bezier()Custom speed curve
steps()Movement in fixed steps

ease

The ease timing function starts slowly, speeds up, and slows down again near the end.

Ease
.box {
transition:
transform 1s ease;
}
ease Is the Default

If no timing function is specified, the browser uses ease.

linear

The linear timing function keeps the transition speed constant from beginning to end.

Linear
.box {
transition:
transform 1s linear;
}
Linear Speed
Time
0% 25% 50% 75% 100%
│---------│---------│---------│---------│
Speed remains constant

ease-in

The ease-in timing function starts slowly and accelerates toward the end.

Ease In
.box {
transition:
transform 1s ease-in;
}
Ease-In Speed
Start End
Slow ─────► Faster ─────► Fast

ease-out

The ease-out timing function starts quickly and slows down near the end.

Ease Out
.box {
transition:
transform 1s ease-out;
}
Ease-Out Speed
Start End
Fast ─────► Slower ─────► Slow

ease-in-out

The ease-in-out timing function starts slowly, speeds up in the middle, and slows down again near the end.

Ease In Out
.box {
transition:
transform 1s ease-in-out;
}

Timing Function Comparison

Timing FunctionStartMiddleEnd
easeSlowFastSlow
linearConstantConstantConstant
ease-inSlowFasterFast
ease-outFastSlowerSlow
ease-in-outSlowFastSlow
Speed Patterns
ease
Slow ───► Fast ───► Slow
linear
Same ───► Same ───► Same
ease-in
Slow ───► Medium ───► Fast
ease-out
Fast ───► Medium ───► Slow
ease-in-out
Slow ───► Fast ───► Slow

Example 3: Timing Functions

HTML
<div class="track">
<div class="runner ease">ease</div>
</div>
<div class="track">
<div class="runner linear">linear</div>
</div>
<div class="track">
<div class="runner ease-in">ease-in</div>
</div>
<div class="track">
<div class="runner ease-out">ease-out</div>
</div>
CSS
.track {
margin-bottom: 12px;
background: #f1f2f6;
border-radius: 8px;
}
.runner {
width: 90px;
padding: 12px;
background: #6c5ce7;
color: white;
text-align: center;
border-radius: 8px;
transition:
transform 2s;
}
.track:hover .runner {
transform:
translateX(300px);
}
.ease {
transition-timing-function:
ease;
}
.linear {
transition-timing-function:
linear;
}
.ease-in {
transition-timing-function:
ease-in;
}
.ease-out {
transition-timing-function:
ease-out;
}
Live Preview

cubic-bezier()

The cubic-bezier() function creates a custom transition speed curve.

Custom Timing Curve
.box {
transition:
transform
0.6s
cubic-bezier(
0.68,
-0.55,
0.27,
1.55
);
}
Cubic Bezier Structure
cubic-bezier(
x1,
y1,
x2,
y2
)
Start Point ──► Control Point 1
Control Point 2
──► End Point
Useful for Custom Motion

Custom cubic-bezier curves can create effects such as overshooting, bouncing-like movement, and carefully designed interface motion.

steps()

The steps() timing function divides a transition into a fixed number of jumps instead of creating continuous smooth movement.

Four Steps
.box {
transition:
transform
2s
steps(4);
}
Stepped Movement
Start
Position 1
│
▼
Position 2
│
▼
Position 3
│
▼
Position 4
│
▼
End
Useful for Frame-Like Changes

steps() is useful when a property should change in visible stages rather than through continuous interpolation.

transition-delay

The transition-delay property defines how long the browser waits before starting a transition.

One Second Delay
.box {
transition-property:
transform;
transition-duration:
0.5s;
transition-delay:
1s;
}
State Changes
↓
Wait for Delay
↓
Transition Starts
↓
Duration Runs
↓
Final State Reached

Positive Delay

A positive delay waits before the transition starts.

Positive Delay
.box {
transition:
transform
0.5s
ease
1s;
}
Positive Delay Timeline
State Change
0s ─────────────── 1s ─────────────── 1.5s
│ │ │
Wait Start End
Transition

Negative Delay

A negative transition delay makes the transition behave as if it had already been running for part of its duration.

Negative Delay
.box {
transition:
transform
2s
linear
-0.5s;
}
Negative Delay Does Not Wait

A negative delay starts immediately but begins from a later point in the transition progress.

Example 4: Delayed Transition

HTML
<div class="delay-box">
Hover and Wait
</div>
CSS
.delay-box {
width: 180px;
padding: 24px;
background: #6c5ce7;
color: white;
text-align: center;
border-radius: 10px;
transition:
transform
0.6s
ease
0.8s;
}
.delay-box:hover {
transform:
translateX(180px);
}
Live Preview

Transition Shorthand

The transition shorthand combines the transition property name, duration, timing function, and delay into one declaration.

Shorthand Syntax
.element {
transition:
property
duration
timing-function
delay;
}
Example
.button {
transition:
background-color
0.3s
ease
0s;
}

Shorthand Order

When two time values are present in the transition shorthand, the first is interpreted as the duration and the second as the delay.

Duration and Delay
.box {
transition:
transform
0.5s
ease
1s;
}
ValueMeaning
transformProperty
0.5sDuration
easeTiming function
1sDelay
Duration Comes Before Delay

If two time values are used, remember: first time is duration, second time is delay.

Example 5: Shorthand Transition

HTML
<button class="shorthand-button">
Hover Me
</button>
CSS
.shorthand-button {
padding: 14px 28px;
border: none;
background: #6c5ce7;
color: white;
border-radius: 8px;
transition:
transform
0.3s
ease-out;
}
.shorthand-button:hover {
transform:
translateY(-6px)
scale(1.05);
}
Live Preview

Multiple Transitions

Different properties can have different durations, timing functions, and delays by separating transition definitions with commas.

Multiple Transitions
.card {
transition:
transform 0.3s ease,
background-color 0.5s linear,
box-shadow 0.4s ease-out;
}
Each Comma Starts a New Transition

Every comma-separated transition can define its own property, duration, timing function, and delay.

Example 6: Multiple Properties

HTML
<article class="multi-card">
<h3>CSS Transition</h3>
<p>
Hover over this card.
</p>
</article>
CSS
.multi-card {
width: 260px;
padding: 30px;
background: white;
border-radius: 14px;
box-shadow:
0 8px 20px
rgba(0, 0, 0, 0.08);
transition:
transform 0.3s ease,
background-color 0.5s ease,
color 0.4s ease,
box-shadow 0.3s ease;
}
.multi-card:hover {
transform:
translateY(-10px);
background-color:
#6c5ce7;
color: white;
box-shadow:
0 18px 40px
rgba(108, 92, 231, 0.3);
}
Live Preview

Transition Trigger

A transition starts when a transitionable property changes from one value to another.

:hover

Starts when the pointer enters or leaves an element.

:focus

Starts when an element gains or loses keyboard focus.

:active

Starts while an element is being activated.

:checked

Starts when a form control changes checked state.

Class Change

Starts when JavaScript adds or removes a class.

Style Change

Starts when a property value changes dynamically.

Hover Transitions

The :hover pseudo-class is one of the most common ways to trigger a CSS transition.

Hover Transition
.card {
transform:
translateY(0);
transition:
transform 0.3s ease;
}
.card:hover {
transform:
translateY(-10px);
}
Put transition on the Base State

Placing transition on the normal element allows the property to transition both when entering and leaving the changed state.

Focus Transitions

Transitions can improve focus feedback for keyboard and form interactions.

Input Focus Transition
.input {
border:
2px solid #dfe6e9;
box-shadow:
0 0 0 0
rgba(108, 92, 231, 0);
transition:
border-color 0.3s ease,
box-shadow 0.3s ease;
}
.input:focus {
border-color:
#6c5ce7;
box-shadow:
0 0 0 4px
rgba(108, 92, 231, 0.15);
}

Class-Based Transitions

JavaScript can add or remove a class, and CSS transitions can smoothly animate the resulting property changes.

HTML
<div class="panel" id="panel">
Menu
</div>
<button id="toggleButton">
Toggle Panel
</button>
CSS
.panel {
transform:
translateX(-100%);
opacity: 0;
transition:
transform 0.4s ease,
opacity 0.4s ease;
}
.panel.open {
transform:
translateX(0);
opacity: 1;
}
JavaScript
const panel =
document.querySelector('#panel');
const button =
document.querySelector('#toggleButton');
button.addEventListener('click', () => {
panel.classList.toggle('open');
});

Example 7: Expanding Card

HTML
<article class="expand-card">
<div class="card-icon">
CSS
</div>
<h3>Transitions</h3>
<p>
Smooth property changes.
</p>
</article>
CSS
.expand-card {
width: 260px;
padding: 30px;
background: white;
border-radius: 16px;
box-shadow:
0 10px 30px
rgba(0, 0, 0, 0.08);
transition:
transform 0.35s ease,
box-shadow 0.35s ease;
}
.card-icon {
width: 60px;
height: 60px;
display: grid;
place-items: center;
background: #6c5ce7;
color: white;
border-radius: 14px;
transition:
transform 0.35s ease,
border-radius 0.35s ease;
}
.expand-card:hover {
transform:
translateY(-10px)
scale(1.03);
box-shadow:
0 20px 50px
rgba(0, 0, 0, 0.16);
}
.expand-card:hover .card-icon {
transform:
rotate(10deg)
scale(1.1);
border-radius: 50%;
}
Live Preview

Transitions with Transform

The transform property is one of the most commonly transitioned properties because it supports movement, rotation, and scaling.

Transform Transition
.button {
transform:
translateY(0)
scale(1);
transition:
transform 0.3s ease;
}
.button:hover {
transform:
translateY(-5px)
scale(1.05);
}
Transform Works Well for Motion

For visual movement, translate() is commonly preferred over repeatedly changing layout-related properties.

Example 8: Interactive Button

HTML
<button class="action-button">
<span>Get Started</span>
<span class="arrow">→</span>
</button>
CSS
.action-button {
display: inline-flex;
align-items: center;
gap: 10px;
padding: 14px 24px;
border: none;
background: #6c5ce7;
color: white;
border-radius: 10px;
cursor: pointer;
transition:
transform 0.3s ease,
background-color 0.3s ease,
box-shadow 0.3s ease;
}
.arrow {
transition:
transform 0.3s ease;
}
.action-button:hover {
transform:
translateY(-4px);
background-color:
#5f4dd0;
box-shadow:
0 12px 24px
rgba(108, 92, 231, 0.3);
}
.action-button:hover .arrow {
transform:
translateX(6px);
}
Live Preview

Transitions with Opacity

The opacity property is commonly transitioned to create fade-in and fade-out effects.

Fade Transition
.message {
opacity: 0;
transition:
opacity 0.4s ease;
}
.message.visible {
opacity: 1;
}
Opacity Does Not Remove Layout Space

An element with opacity: 0 is invisible, but it still occupies its normal layout space and may still receive pointer interaction.

Example 9: Fade Effect

HTML
<div class="image-card">
<img
src="mountain.jpg"
alt="Mountain"
>
<div class="overlay">
<h3>Explore Nature</h3>
<p>
Discover beautiful places.
</p>
</div>
</div>
CSS
.image-card {
position: relative;
width: 320px;
overflow: hidden;
border-radius: 16px;
}
.image-card img {
display: block;
width: 100%;
transition:
transform 0.5s ease;
}
.overlay {
position: absolute;
inset: 0;
display: grid;
place-content: center;
padding: 30px;
background:
rgba(45, 52, 54, 0.75);
color: white;
text-align: center;
opacity: 0;
transition:
opacity 0.4s ease;
}
.image-card:hover img {
transform:
scale(1.08);
}
.image-card:hover .overlay {
opacity: 1;
}
Live Preview

Properties That Can Transition

Many CSS properties can transition because the browser can calculate meaningful intermediate values between their starting and ending states.

CategoryExamples
Colorscolor, background-color, border-color
Dimensionswidth, height, max-width, max-height
Spacingmargin, padding, gap
Positiontop, right, bottom, left
Transparencyopacity
Transformstransform
Bordersborder-width, border-radius
Shadowsbox-shadow, text-shadow
Typographyfont-size, letter-spacing, line-height

Properties That Cannot Transition

Some CSS properties do not have meaningful intermediate values and therefore cannot transition smoothly in the traditional way.

Property ChangeProblem
display: none to blockNo continuous intermediate display value
position: static to absoluteDiscrete layout mode change
font-family changesDifferent font resources cannot be smoothly interpolated
Some keyword valuesNo numeric or interpolated path between states

Why display Cannot Transition

Traditional CSS transitions cannot smoothly interpolate between display: none and display: block because there are no meaningful intermediate display states.

This Does Not Fade Smoothly
.message {
display: none;
transition:
display 0.5s;
}
.message.visible {
display: block;
}
Why It Jumps
display: none
│
│ No Intermediate Values
▼
display: block

Alternatives to display

For common reveal and hide effects, properties such as opacity, visibility, transform, and dimensions can be combined.

Fade and Move
.message {
opacity: 0;
visibility: hidden;
transform:
translateY(10px);
transition:
opacity 0.3s ease,
transform 0.3s ease,
visibility 0.3s;
}
.message.visible {
opacity: 1;
visibility: visible;
transform:
translateY(0);
}
Combine Properties for Better Reveals

Opacity creates fading, transform creates movement, and visibility can prevent an invisible element from remaining interactable.

Transition Interruption

A transition can be interrupted before it finishes.

For example, if a user moves the pointer away from a button halfway through a hover transition, the browser begins transitioning from the current intermediate value toward the original value.

Interrupted Transition
Start
Scale 1
│
▼
Scale 1.05
│
│ Pointer Leaves Early
▼
Reverse from Current Value
│
▼
Scale 1
Transitions Respond to Current State

The browser does not need to finish the first transition before moving toward a new target value.

Reversing Transitions

When the changed state is removed, the browser normally transitions the property back to its original value.

Forward and Reverse
.button {
transform:
scale(1);
transition:
transform 0.3s ease;
}
.button:hover {
transform:
scale(1.1);
}
Normal State
↓
Pointer Enters
↓
Transition to Hover State
↓
Pointer Leaves
↓
Transition Back to Normal State
Keep transition on the Base Rule

If transition is placed only inside :hover, the return to the normal state may not use the same smooth transition.

Transition Events

JavaScript can listen for events related to CSS transitions.

EventWhen It Occurs
transitionrunTransition is created
transitionstartTransition begins after delay
transitionendTransition finishes
transitioncancelTransition is cancelled

transitionend Event

The transitionend event runs when a CSS transition completes.

Listen for Transition Completion
const card =
document.querySelector('.card');
card.addEventListener(
'transitionend',
(event) => {
console.log(
'Finished:',
event.propertyName
);
}
);
One Event Can Fire per Property

If several properties transition, transitionend can fire separately for each transitioned property.

Transition Performance

Different CSS properties can require different amounts of browser rendering work when they change.

Often Better for Motion

  • transform
  • opacity
  • Commonly handled efficiently.
  • Often avoids repeated layout calculations.

Can Require More Work

  • width
  • height
  • top and left in complex layouts
  • Can trigger layout and repaint work.
Preferred Visual Movement
.card {
transition:
transform 0.3s ease;
}
.card:hover {
transform:
translateY(-10px);
}
Prefer transform for Visual Movement

When an element only needs to move visually, transitioning transform is commonly more suitable than repeatedly changing layout dimensions or positions.

prefers-reduced-motion

Some users prefer reduced motion because large or frequent movement can be uncomfortable or distracting.

Respect Reduced Motion Preference
.card {
transition:
transform 0.4s ease;
}
@media (
prefers-reduced-motion:
reduce
) {
.card {
transition: none;
}
}
Accessibility Matters

Important interactions should remain understandable and usable even when motion is reduced or removed.

Complete Transition Example

The following example combines background colors, transforms, opacity, shadows, multiple transitions, delays, timing functions, and interactive child elements.

HTML
<section class="course-section">
<div class="section-heading">
<span class="lesson-badge">
Lesson 21
</span>
<h2>
Master CSS Transitions
</h2>
<p>
Hover over the course cards
to explore smooth interactions.
</p>
</div>
<div class="course-grid">
<article class="course-card">
<div class="course-icon">
🎨
</div>
<span class="course-label">
Beginner
</span>
<h3>
Color Transitions
</h3>
<p>
Create smooth visual changes
between different colors.
</p>
<a href="#">
Explore Lesson
<span class="arrow">
→
</span>
</a>
</article>
<article class="course-card">
<div class="course-icon">
↗
</div>
<span class="course-label">
Intermediate
</span>
<h3>
Transform Transitions
</h3>
<p>
Move, rotate, and scale
elements smoothly.
</p>
<a href="#">
Explore Lesson
<span class="arrow">
→
</span>
</a>
</article>
<article class="course-card">
<div class="course-icon">
✨
</div>
<span class="course-label">
Advanced
</span>
<h3>
Custom Timing
</h3>
<p>
Control motion using
custom timing curves.
</p>
<a href="#">
Explore Lesson
<span class="arrow">
→
</span>
</a>
</article>
</div>
</section>
CSS
.course-section {
padding: 50px;
background: #f5f6fa;
border-radius: 24px;
}
.section-heading {
max-width: 650px;
margin-bottom: 35px;
}
.lesson-badge {
display: inline-block;
padding: 7px 14px;
background: #6c5ce7;
color: white;
border-radius: 999px;
transition:
transform 0.3s ease,
background-color 0.3s ease;
}
.lesson-badge:hover {
transform:
rotate(-4deg)
scale(1.05);
background-color:
#5f4dd0;
}
.course-grid {
display: grid;
grid-template-columns:
repeat(
auto-fit,
minmax(220px, 1fr)
);
gap: 24px;
}
.course-card {
position: relative;
padding: 30px;
overflow: hidden;
background: white;
color: #2d3436;
border:
1px solid #dfe6e9;
border-radius: 18px;
box-shadow:
0 8px 24px
rgba(0, 0, 0, 0.06);
transition:
transform 0.35s ease,
background-color 0.45s ease,
color 0.35s ease,
border-color 0.35s ease,
box-shadow 0.35s ease;
}
.course-card::before {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 5px;
background: #6c5ce7;
transform:
scaleX(0);
transform-origin:
left center;
transition:
transform 0.4s ease;
}
.course-icon {
width: 60px;
height: 60px;
display: grid;
place-items: center;
margin-bottom: 20px;
background:
rgba(108, 92, 231, 0.1);
border-radius: 14px;
font-size: 1.8rem;
transition:
transform 0.4s
cubic-bezier(
0.68,
-0.55,
0.27,
1.55
),
background-color 0.3s ease;
}
.course-label {
display: inline-block;
margin-bottom: 10px;
color: #6c5ce7;
font-size: 0.8rem;
font-weight: 700;
transition:
color 0.3s ease;
}
.course-card h3 {
margin-bottom: 12px;
}
.course-card p {
color: #636e72;
transition:
color 0.35s ease;
}
.course-card a {
display: inline-flex;
align-items: center;
gap: 8px;
margin-top: 18px;
color: #6c5ce7;
font-weight: 600;
text-decoration: none;
transition:
color 0.3s ease;
}
.arrow {
transition:
transform 0.3s ease;
}
.course-card:hover {
transform:
translateY(-12px);
background-color:
#6c5ce7;
color: white;
border-color:
#6c5ce7;
box-shadow:
0 22px 50px
rgba(108, 92, 231, 0.25);
}
.course-card:hover::before {
transform:
scaleX(1);
}
.course-card:hover .course-icon {
transform:
rotate(8deg)
scale(1.12);
background-color:
white;
}
.course-card:hover .course-label,
.course-card:hover p,
.course-card:hover a {
color: white;
}
.course-card:hover .arrow {
transform:
translateX(7px);
}
Live Preview

Browser Rendering Flow

When a transitionable property changes, the browser compares the current value with the new value and calculates intermediate values over time.

Read Initial CSS Value
↓
Detect State Change
↓
Read New Property Value
↓
Check transition-property
↓
Read Duration
↓
Apply Delay
↓
Apply Timing Function
↓
Calculate Intermediate Values
↓
Render Frames
↓
Reach Final Value
Transition Processing
Initial State
│
▼
Property Value Changes
│
▼
Is Property Transitionable?
│
┌──┴──┐
│ │
No Yes
│ │
▼ ▼
Jump Read Transition Settings
│
▼
Apply Delay
│
▼
Start Duration
│
▼
Timing Function
│
▼
Calculate Intermediate Values
│
▼
Render Frames
│
▼
Final State

Real-World Applications

Buttons

Create smooth hover, focus, and active states.

Cards

Lift, scale, rotate, and change shadows smoothly.

Navigation Menus

Slide menus and dropdown panels into view.

Image Galleries

Zoom images and fade overlays.

Forms

Smoothly highlight focused inputs and validation states.

Tooltips

Fade and move helpful information into view.

Toggles

Move switches and change colors smoothly.

Dashboards

Reveal panels and update interactive controls.

Advantages

Smooth Interfaces

Replace abrupt changes with gradual visual feedback.

Easy to Learn

Simple transitions require only a few CSS properties.

Better Interaction

Improve hover, focus, and active states.

Flexible Control

Control property, duration, speed curve, and delay.

Multiple Properties

Transition several properties with independent settings.

Efficient Motion

Transform and opacity transitions can provide smooth visual effects.

Automatic Reversal

Transitions naturally move back toward original values when states change.

Works with JavaScript

Class changes can trigger transitions without manually calculating frames.

Common Beginner Mistakes

Forgetting transition-duration

The default duration is 0s, so no smooth transition will be visible.

Putting transition Only on :hover

The return to the original state may not transition as expected.

Trying to Transition display

Traditional transitions cannot smoothly interpolate between display: none and display: block.

Forgetting the Initial Value

A transition needs a starting value and a changed target value.

Using all Everywhere

Unexpected changed properties may begin transitioning.

Confusing Duration and Delay

Duration controls how long the transition runs, while delay controls how long it waits before starting.

Reversing Shorthand Time Values

The first time value is duration and the second is delay.

Forgetting Time Units

Values such as 0.3 require a time unit like s or ms.

Using Very Long Durations

Slow interface transitions can make the website feel unresponsive.

Using Very Short Durations

Extremely fast transitions may appear almost instant.

Transitioning Too Many Properties

Unnecessary transitions can make the interface difficult to understand and maintain.

Using width for Simple Motion

Changing dimensions can require more layout work than using transform for visual movement.

Forgetting Multiple Transition Commas

Separate transition definitions must be separated by commas.

Expecting linear to Feel Natural Everywhere

Constant speed can feel mechanical for many interface interactions.

Misunderstanding ease-in

ease-in starts slowly and finishes faster.

Misunderstanding ease-out

ease-out starts quickly and finishes slowly.

Using Large Delays for Important Feedback

Users should not wait unnecessarily for important interaction feedback.

Forgetting Interrupted Transitions

Users can change state before a transition finishes.

Hiding Elements with opacity Only

An element with opacity: 0 may still receive interaction.

Ignoring Reduced Motion Preferences

Some users prefer reduced or removed motion.

Best Practices

  • Use transitions to communicate meaningful state changes.
  • Keep interface transitions subtle and purposeful.
  • Place transition declarations on the base element in most cases.
  • Define an initial property value.
  • Define a changed property value.
  • Use transition-property to control exactly what changes smoothly.
  • Prefer explicit property names over all when practical.
  • Use all only when every changed transitionable property should animate.
  • Always provide a duration greater than zero for visible transitions.
  • Use seconds or milliseconds consistently.
  • Remember that 1000ms equals 1s.
  • Keep common interface transitions relatively short.
  • Use approximately 0.2s to 0.4s for many simple interactions.
  • Use longer durations only when the motion needs to be observed clearly.
  • Avoid transitions that make interfaces feel slow.
  • Choose timing functions based on the desired feeling.
  • Use ease for general-purpose transitions.
  • Use linear when constant speed is appropriate.
  • Use ease-in when movement should accelerate.
  • Use ease-out when movement should decelerate.
  • Use ease-in-out for smooth starts and endings.
  • Use cubic-bezier() when a custom motion curve is necessary.
  • Keep custom timing curves understandable and consistent.
  • Use steps() only when discrete movement is intentional.
  • Use transition-delay carefully.
  • Avoid delaying important interaction feedback.
  • Remember that positive delay waits before starting.
  • Remember that negative delay starts partway through the transition.
  • Use the transition shorthand for concise declarations.
  • Remember the shorthand order: property, duration, timing function, delay.
  • Remember that the first time value is duration.
  • Remember that the second time value is delay.
  • Separate multiple transitions with commas.
  • Give different properties different durations when appropriate.
  • Keep related transition definitions grouped together.
  • Use :hover transitions for pointer interactions.
  • Do not rely only on :hover for important functionality.
  • Use :focus and :focus-visible for keyboard interaction feedback.
  • Use :active for press feedback where appropriate.
  • Use class changes for state-based transitions.
  • Keep JavaScript responsible for state changes and CSS responsible for visual transitions when possible.
  • Use transform for visual movement.
  • Use translate() instead of layout properties for simple visual motion.
  • Use scale() for subtle zoom effects.
  • Use rotate() for intentional rotational feedback.
  • Avoid excessive scaling that causes overlap.
  • Use opacity for fade effects.
  • Remember that opacity: 0 elements still occupy layout space.
  • Combine opacity with visibility when hidden elements should not remain interactable.
  • Use transform and opacity together for polished reveal effects.
  • Do not expect display: none and display: block to transition traditionally.
  • Use opacity, visibility, transform, or dimensions for common reveal effects.
  • Understand whether a property can be interpolated.
  • Test transitions when states change rapidly.
  • Expect transitions to be interrupted.
  • Ensure interrupted transitions reverse naturally.
  • Avoid transition effects that require users to wait before clicking.
  • Keep interactive targets stable during transitions.
  • Do not move buttons so far that they become difficult to click.
  • Avoid large layout shifts during interaction.
  • Use transform instead of width or height when only visual movement is required.
  • Prefer transform and opacity for common high-frequency visual effects.
  • Avoid transitioning many expensive properties simultaneously.
  • Test transitions on lower-powered devices.
  • Use browser developer tools to inspect active transitions.
  • Check computed transition values when debugging.
  • Verify that transition-property matches the property that actually changes.
  • Check for overridden transition declarations.
  • Check commas when defining multiple transitions.
  • Check time units when a transition does not run.
  • Check whether the property is transitionable.
  • Keep transition durations consistent across similar components.
  • Create a small motion system for larger projects.
  • Use similar durations for similar interactions.
  • Use consistent timing curves across related components.
  • Make faster transitions for small changes.
  • Use slightly longer transitions for larger movement.
  • Avoid decorative motion that distracts from content.
  • Do not transition every possible property.
  • Use color transitions for hover and focus feedback.
  • Use border-color transitions for form states.
  • Use box-shadow transitions carefully.
  • Use border-radius transitions only when shape change is meaningful.
  • Use transitions for menus and panels without hiding essential controls.
  • Ensure keyboard users can trigger equivalent state changes.
  • Keep focus indicators visible during transitions.
  • Do not remove outlines without providing accessible alternatives.
  • Use semantic HTML beneath visual effects.
  • Test transitions on touch devices.
  • Remember that hover behavior differs on touch screens.
  • Test transitions at narrow screen widths.
  • Test transitions at large screen widths.
  • Check whether transformed elements overflow their containers.
  • Use overflow carefully with moving elements.
  • Avoid clipping focus indicators.
  • Respect prefers-reduced-motion.
  • Reduce or remove non-essential motion when requested by the user.
  • Keep functionality available when transitions are disabled.
  • Do not depend on motion alone to communicate important information.
  • Use transitionend only when code truly needs to react after completion.
  • Remember that transitionend may fire once for each transitioned property.
  • Handle cancelled or interrupted transitions when necessary.
  • Avoid adding complex JavaScript when CSS transitions can solve the visual requirement.
  • Use CSS transitions for simple two-state changes.
  • Use CSS animations for multi-step or repeating sequences.
  • Choose the simplest motion technique that solves the problem.
  • Keep transitions smooth, short, consistent, and purposeful.
Remember the Core Transition Formula

Choose what changes, decide how long it takes, control how the speed changes, and optionally decide how long to wait before starting.

Frequently Asked Questions

CSS Transition allows a property value to change smoothly over a specified duration instead of changing instantly.

They are transition-property, transition-duration, transition-timing-function, and transition-delay.

It defines which CSS property should transition smoothly.

It defines how long the transition takes to complete.

The default duration is 0s, which means the change appears instant.

Transitions commonly use seconds with s or milliseconds with ms.

One second equals 1000 milliseconds.

It controls how the transition speed changes during the duration.

The default timing function is ease.

linear keeps the transition speed constant from beginning to end.

ease-in starts slowly and accelerates toward the end.

ease-out starts quickly and slows down near the end.

ease-in-out starts slowly, speeds up in the middle, and slows down near the end.

cubic-bezier() creates a custom transition timing curve.

steps() divides a transition into a fixed number of visible jumps.

It defines how long the browser waits before starting the transition.

Yes. A negative delay starts immediately as if the transition had already been running.

It combines the property, duration, timing function, and delay into one declaration.

The common order is property, duration, timing function, and delay.

The first time value is the duration.

The second time value is the delay.

Yes. Separate multiple transition definitions with commas.

It transitions every changed property that supports interpolation.

No. Explicitly listing properties is often clearer and prevents unexpected transitions.

It is usually placed on the base element so both forward and reverse state changes transition smoothly.

Yes. Hover transitions are one of the most common uses of CSS transitions.

Yes. Focus state changes can transition properties such as border color and box shadow.

Yes. JavaScript can change classes or styles, and CSS can transition the resulting property changes.

Traditional CSS transitions cannot smoothly interpolate between these display values.

Common alternatives include opacity, visibility, transform, and dimensions.

No. The element remains in layout and may still receive interaction.

The browser transitions from the current intermediate value toward the new target value.

When the property returns to its original value, the browser can transition smoothly back.

transitionend is a JavaScript event that fires when a CSS transition finishes.

Yes. It can fire separately for each transitioned property.

transform and opacity are commonly preferred for many visual motion effects.

No, but width changes can require layout recalculation. Use transform when only visual movement or scaling is needed.

It is a media feature that allows CSS to respond when a user prefers less motion.

A transition usually moves between property states when a change occurs, while an animation can define multiple keyframes, repeat, and run automatically.

The next lesson covers CSS Animation, including @keyframes, animation properties, duration, delay, iteration count, direction, fill mode, timing functions, and practical animation examples.

Key Takeaways

  • CSS transitions create smooth changes between property values.
  • A transition needs an initial value and a changed value.
  • transition-property defines what changes smoothly.
  • transition-duration defines how long the change takes.
  • The default duration is 0s.
  • Time values can use seconds or milliseconds.
  • transition-timing-function controls the speed pattern.
  • ease starts slowly, speeds up, and slows down.
  • linear uses constant speed.
  • ease-in starts slowly.
  • ease-out ends slowly.
  • ease-in-out starts and ends slowly.
  • cubic-bezier() creates custom timing curves.
  • steps() creates discrete jumps.
  • transition-delay controls when the transition begins.
  • Positive delay waits before starting.
  • Negative delay starts partway through the transition.
  • The transition shorthand combines all transition settings.
  • The first shorthand time value is duration.
  • The second shorthand time value is delay.
  • Multiple transitions are separated with commas.
  • Transitions can be triggered by hover, focus, active states, and class changes.
  • Transitions should normally be placed on the base element.
  • Transform and opacity are commonly useful for smooth visual effects.
  • Traditional transitions cannot smoothly animate display changes.
  • Interrupted transitions continue from their current value.
  • Transitions can automatically reverse when states change back.
  • JavaScript can listen for transition events.
  • prefers-reduced-motion helps respect user motion preferences.
  • Transitions are best for simple state-to-state changes.

Summary

CSS Transition allows property values to change smoothly over time instead of changing instantly.

A transition requires a property value to change from an initial state to a new state.

The transition-property property defines which property should transition.

The transition-duration property defines how long the transition takes.

The transition-timing-function property controls how the speed changes during the transition.

Common timing functions include ease, linear, ease-in, ease-out, and ease-in-out.

The cubic-bezier() function creates custom timing curves, while steps() divides a transition into fixed jumps.

The transition-delay property controls how long the browser waits before starting the transition.

The transition shorthand combines the property, duration, timing function, and delay.

Multiple properties can transition independently using comma-separated transition definitions.

Transitions can be triggered by pseudo-classes such as :hover and :focus or by JavaScript class changes.

The transform and opacity properties are commonly used for smooth visual movement and fading.

Traditional transitions cannot smoothly interpolate between display: none and display: block.

Transitions can be interrupted and reversed naturally when the target state changes.

JavaScript transition events such as transitionend can detect when a transition finishes.

For accessible interfaces, non-essential motion should be reduced when the user prefers reduced motion.

CSS transitions are ideal for smooth state changes such as button hover effects, card interactions, form focus states, menus, overlays, and interface feedback.

In the next lesson, you will learn CSS Animation, including @keyframes, animation properties, duration, delays, iteration counts, directions, fill modes, timing functions, and complete animation examples.

Next Lesson →

Animation