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.
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.
.button {
background: #6c5ce7;
}
.button:hover {
background: #00b894;
}Without a transition, the background color changes immediately when the pointer enters the button.
.button {
background: #6c5ce7;
transition:
background 0.3s ease;
}
.button:hover {
background: #00b894;
}Without Transition
Purple ─────────────────────► Green
Instant Change
With Transition
Purple ──► Blue-Purple ──► Blue-Green ──► Green
0s 0.15s 0.3sWhy 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 Concept | CSS Transition |
|---|---|
| Starting speed | Initial property value |
| Target speed | Final property value |
| Acceleration time | transition-duration |
| Acceleration pattern | transition-timing-function |
| Waiting before moving | transition-delay |
| What changes | transition-property |
Start
0 km/h
│
▼
10 km/h
│
▼
25 km/h
│
▼
45 km/h
│
▼
60 km/h
Final State
CSS
Initial Value
│
▼
Intermediate Values
│
▼
Final ValueHow Transitions Work
A transition needs an initial property value and a changed property value.
.box {
width: 150px;
transition:
width 1s ease;
}
.box:hover {
width: 300px;
}Time Width
0.00s 150px
0.20s 175px
0.40s 210px
0.60s 250px
0.80s 280px
1.00s 300pxYou define the starting value, final value, and transition behavior. The browser calculates the values between them.
Basic Transition Syntax
.element {
transition-property: background-color;
transition-duration: 0.3s;
transition-timing-function: ease;
transition-delay: 0s;
}.element {
transition:
background-color
0.3s
ease
0s;
}| Part | Purpose |
|---|---|
| transition-property | Defines which property changes smoothly |
| transition-duration | Defines how long the change takes |
| transition-timing-function | Defines the speed pattern |
| transition-delay | Defines how long to wait before starting |
Transition Properties
| Property | Purpose | Example |
|---|---|---|
| transition-property | Property to animate | transform |
| transition-duration | Length of transition | 0.3s |
| transition-timing-function | Speed curve | ease |
| transition-delay | Waiting time | 0.2s |
| transition | Shorthand for all transition values | transform 0.3s ease |
transition-property
The transition-property property defines which CSS property should change smoothly.
.button {
transition-property:
background-color;
}.card {
transition-property:
transform;
}.image {
transition-property:
opacity;
}| Value | Meaning |
|---|---|
| none | No property transitions |
| all | All transitionable changed properties |
| Property name | Only the named property |
| Multiple names | Several comma-separated properties |
Example 1: Background Color
<button class="color-button">
Hover Me
</button>.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;
}Multiple Transition Properties
Several properties can be transitioned by separating their names with commas.
.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.
.card {
transition-property: all;
transition-duration: 0.3s;
}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.
.button {
transition-duration: 0.2s;
}.button {
transition-duration: 2s;
}| Duration | General Feeling |
|---|---|
| 0s | Instant change |
| 0.1s - 0.2s | Very fast |
| 0.2s - 0.4s | Common interface speed |
| 0.5s - 1s | Noticeably slow |
| More than 1s | Usually dramatic or demonstrative |
A transition will not appear smooth unless a duration greater than zero is provided.
Time Units
| Unit | Meaning | Example |
|---|---|---|
| s | Seconds | 0.5s |
| ms | Milliseconds | 500ms |
.one {
transition-duration: 0.5s;
}
.two {
transition-duration: 500ms;
}Both seconds and milliseconds are valid. Use the format that is easiest to read consistently in your project.
Example 2: Different Durations
<div class="duration-demo fast">
Fast
</div>
<div class="duration-demo medium">
Medium
</div>
<div class="duration-demo slow">
Slow
</div>.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;
}transition-timing-function
The transition-timing-function property controls how the speed of a transition changes during its duration.
.box {
transition-timing-function:
ease-in-out;
}| Value | Behavior |
|---|---|
| ease | Slow start, fast middle, slow end |
| linear | Constant speed |
| ease-in | Slow start |
| ease-out | Slow end |
| ease-in-out | Slow 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.
.box {
transition:
transform 1s ease;
}If no timing function is specified, the browser uses ease.
linear
The linear timing function keeps the transition speed constant from beginning to end.
.box {
transition:
transform 1s linear;
}Time
0% 25% 50% 75% 100%
│---------│---------│---------│---------│
Speed remains constantease-in
The ease-in timing function starts slowly and accelerates toward the end.
.box {
transition:
transform 1s ease-in;
}Start End
Slow ─────► Faster ─────► Fastease-out
The ease-out timing function starts quickly and slows down near the end.
.box {
transition:
transform 1s ease-out;
}Start End
Fast ─────► Slower ─────► Slowease-in-out
The ease-in-out timing function starts slowly, speeds up in the middle, and slows down again near the end.
.box {
transition:
transform 1s ease-in-out;
}Timing Function Comparison
| Timing Function | Start | Middle | End |
|---|---|---|---|
| ease | Slow | Fast | Slow |
| linear | Constant | Constant | Constant |
| ease-in | Slow | Faster | Fast |
| ease-out | Fast | Slower | Slow |
| ease-in-out | Slow | Fast | Slow |
ease
Slow ───► Fast ───► Slow
linear
Same ───► Same ───► Same
ease-in
Slow ───► Medium ───► Fast
ease-out
Fast ───► Medium ───► Slow
ease-in-out
Slow ───► Fast ───► SlowExample 3: Timing Functions
<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>.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;
}cubic-bezier()
The cubic-bezier() function creates a custom transition speed curve.
.box {
transition:
transform
0.6s
cubic-bezier(
0.68,
-0.55,
0.27,
1.55
);
}cubic-bezier(
x1,
y1,
x2,
y2
)
Start Point ──► Control Point 1
Control Point 2
──► End PointCustom 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.
.box {
transition:
transform
2s
steps(4);
}Start
Position 1
│
▼
Position 2
│
▼
Position 3
│
▼
Position 4
│
▼
Endsteps() 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.
.box {
transition-property:
transform;
transition-duration:
0.5s;
transition-delay:
1s;
}Positive Delay
A positive delay waits before the transition starts.
.box {
transition:
transform
0.5s
ease
1s;
}State Change
0s ─────────────── 1s ─────────────── 1.5s
│ │ │
Wait Start End
TransitionNegative Delay
A negative transition delay makes the transition behave as if it had already been running for part of its duration.
.box {
transition:
transform
2s
linear
-0.5s;
}A negative delay starts immediately but begins from a later point in the transition progress.
Example 4: Delayed Transition
<div class="delay-box">
Hover and Wait
</div>.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);
}Transition Shorthand
The transition shorthand combines the transition property name, duration, timing function, and delay into one declaration.
.element {
transition:
property
duration
timing-function
delay;
}.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.
.box {
transition:
transform
0.5s
ease
1s;
}| Value | Meaning |
|---|---|
| transform | Property |
| 0.5s | Duration |
| ease | Timing function |
| 1s | Delay |
If two time values are used, remember: first time is duration, second time is delay.
Example 5: Shorthand Transition
<button class="shorthand-button">
Hover Me
</button>.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);
}Multiple Transitions
Different properties can have different durations, timing functions, and delays by separating transition definitions with commas.
.card {
transition:
transform 0.3s ease,
background-color 0.5s linear,
box-shadow 0.4s ease-out;
}Every comma-separated transition can define its own property, duration, timing function, and delay.
Example 6: Multiple Properties
<article class="multi-card">
<h3>CSS Transition</h3>
<p>
Hover over this card.
</p>
</article>.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);
}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.
.card {
transform:
translateY(0);
transition:
transform 0.3s ease;
}
.card:hover {
transform:
translateY(-10px);
}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 {
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.
<div class="panel" id="panel">
Menu
</div>
<button id="toggleButton">
Toggle Panel
</button>.panel {
transform:
translateX(-100%);
opacity: 0;
transition:
transform 0.4s ease,
opacity 0.4s ease;
}
.panel.open {
transform:
translateX(0);
opacity: 1;
}const panel =
document.querySelector('#panel');
const button =
document.querySelector('#toggleButton');
button.addEventListener('click', () => {
panel.classList.toggle('open');
});Example 7: Expanding Card
<article class="expand-card">
<div class="card-icon">
CSS
</div>
<h3>Transitions</h3>
<p>
Smooth property changes.
</p>
</article>.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%;
}Transitions with Transform
The transform property is one of the most commonly transitioned properties because it supports movement, rotation, and scaling.
.button {
transform:
translateY(0)
scale(1);
transition:
transform 0.3s ease;
}
.button:hover {
transform:
translateY(-5px)
scale(1.05);
}For visual movement, translate() is commonly preferred over repeatedly changing layout-related properties.
Example 8: Interactive Button
<button class="action-button">
<span>Get Started</span>
<span class="arrow">→</span>
</button>.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);
}Transitions with Opacity
The opacity property is commonly transitioned to create fade-in and fade-out effects.
.message {
opacity: 0;
transition:
opacity 0.4s ease;
}
.message.visible {
opacity: 1;
}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
<div class="image-card">
<img
src="mountain.jpg"
alt="Mountain"
>
<div class="overlay">
<h3>Explore Nature</h3>
<p>
Discover beautiful places.
</p>
</div>
</div>.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;
}Properties That Can Transition
Many CSS properties can transition because the browser can calculate meaningful intermediate values between their starting and ending states.
| Category | Examples |
|---|---|
| Colors | color, background-color, border-color |
| Dimensions | width, height, max-width, max-height |
| Spacing | margin, padding, gap |
| Position | top, right, bottom, left |
| Transparency | opacity |
| Transforms | transform |
| Borders | border-width, border-radius |
| Shadows | box-shadow, text-shadow |
| Typography | font-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 Change | Problem |
|---|---|
| display: none to block | No continuous intermediate display value |
| position: static to absolute | Discrete layout mode change |
| font-family changes | Different font resources cannot be smoothly interpolated |
| Some keyword values | No 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.
.message {
display: none;
transition:
display 0.5s;
}
.message.visible {
display: block;
}display: none
│
│ No Intermediate Values
▼
display: blockAlternatives to display
For common reveal and hide effects, properties such as opacity, visibility, transform, and dimensions can be combined.
.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);
}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.
Start
Scale 1
│
▼
Scale 1.05
│
│ Pointer Leaves Early
▼
Reverse from Current Value
│
▼
Scale 1The 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.
.button {
transform:
scale(1);
transition:
transform 0.3s ease;
}
.button:hover {
transform:
scale(1.1);
}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.
| Event | When It Occurs |
|---|---|
| transitionrun | Transition is created |
| transitionstart | Transition begins after delay |
| transitionend | Transition finishes |
| transitioncancel | Transition is cancelled |
transitionend Event
The transitionend event runs when a CSS transition completes.
const card =
document.querySelector('.card');
card.addEventListener(
'transitionend',
(event) => {
console.log(
'Finished:',
event.propertyName
);
}
);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.
.card {
transition:
transform 0.3s ease;
}
.card:hover {
transform:
translateY(-10px);
}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.
.card {
transition:
transform 0.4s ease;
}
@media (
prefers-reduced-motion:
reduce
) {
.card {
transition: none;
}
}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.
<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>.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);
}Browser Rendering Flow
When a transitionable property changes, the browser compares the current value with the new value and calculates intermediate values over time.
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 StateReal-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
The default duration is 0s, so no smooth transition will be visible.
The return to the original state may not transition as expected.
Traditional transitions cannot smoothly interpolate between display: none and display: block.
A transition needs a starting value and a changed target value.
Unexpected changed properties may begin transitioning.
Duration controls how long the transition runs, while delay controls how long it waits before starting.
The first time value is duration and the second is delay.
Values such as 0.3 require a time unit like s or ms.
Slow interface transitions can make the website feel unresponsive.
Extremely fast transitions may appear almost instant.
Unnecessary transitions can make the interface difficult to understand and maintain.
Changing dimensions can require more layout work than using transform for visual movement.
Separate transition definitions must be separated by commas.
Constant speed can feel mechanical for many interface interactions.
ease-in starts slowly and finishes faster.
ease-out starts quickly and finishes slowly.
Users should not wait unnecessarily for important interaction feedback.
Users can change state before a transition finishes.
An element with opacity: 0 may still receive interaction.
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.
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
What is CSS Transition?
CSS Transition allows a property value to change smoothly over a specified duration instead of changing instantly.
What are the four main transition properties?
They are transition-property, transition-duration, transition-timing-function, and transition-delay.
What does transition-property do?
It defines which CSS property should transition smoothly.
What does transition-duration do?
It defines how long the transition takes to complete.
What is the default transition duration?
The default duration is 0s, which means the change appears instant.
What time units can transitions use?
Transitions commonly use seconds with s or milliseconds with ms.
How many milliseconds are in one second?
One second equals 1000 milliseconds.
What does transition-timing-function do?
It controls how the transition speed changes during the duration.
What is the default timing function?
The default timing function is ease.
What does linear mean?
linear keeps the transition speed constant from beginning to end.
What does ease-in mean?
ease-in starts slowly and accelerates toward the end.
What does ease-out mean?
ease-out starts quickly and slows down near the end.
What does ease-in-out mean?
ease-in-out starts slowly, speeds up in the middle, and slows down near the end.
What is cubic-bezier()?
cubic-bezier() creates a custom transition timing curve.
What does steps() do?
steps() divides a transition into a fixed number of visible jumps.
What does transition-delay do?
It defines how long the browser waits before starting the transition.
Can transition-delay be negative?
Yes. A negative delay starts immediately as if the transition had already been running.
What is the transition shorthand?
It combines the property, duration, timing function, and delay into one declaration.
What is the shorthand order?
The common order is property, duration, timing function, and delay.
If two time values are used, which one is duration?
The first time value is the duration.
If two time values are used, which one is delay?
The second time value is the delay.
Can multiple properties transition?
Yes. Separate multiple transition definitions with commas.
What does transition-property: all do?
It transitions every changed property that supports interpolation.
Should I always use transition: all?
No. Explicitly listing properties is often clearer and prevents unexpected transitions.
Where should the transition property normally be placed?
It is usually placed on the base element so both forward and reverse state changes transition smoothly.
Can :hover trigger a transition?
Yes. Hover transitions are one of the most common uses of CSS transitions.
Can :focus trigger a transition?
Yes. Focus state changes can transition properties such as border color and box shadow.
Can JavaScript trigger CSS transitions?
Yes. JavaScript can change classes or styles, and CSS can transition the resulting property changes.
Can display: none transition to display: block?
Traditional CSS transitions cannot smoothly interpolate between these display values.
What can I use instead of transitioning display?
Common alternatives include opacity, visibility, transform, and dimensions.
Does opacity: 0 remove an element from layout?
No. The element remains in layout and may still receive interaction.
What happens if a transition is interrupted?
The browser transitions from the current intermediate value toward the new target value.
Do transitions automatically reverse?
When the property returns to its original value, the browser can transition smoothly back.
What is transitionend?
transitionend is a JavaScript event that fires when a CSS transition finishes.
Can transitionend fire multiple times?
Yes. It can fire separately for each transitioned property.
Which properties are commonly best for smooth motion?
transform and opacity are commonly preferred for many visual motion effects.
Is changing width always bad?
No, but width changes can require layout recalculation. Use transform when only visual movement or scaling is needed.
What is prefers-reduced-motion?
It is a media feature that allows CSS to respond when a user prefers less motion.
What is the difference between transition and animation?
A transition usually moves between property states when a change occurs, while an animation can define multiple keyframes, repeat, and run automatically.
What comes after CSS Transition?
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.