LearnContact
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;
}

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;
}

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;
}

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);
}

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);
}

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);
}

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%;
}

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);
}

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;
}

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);
}

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

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.