Tutorials Logic, IN info@tutorialslogic.com

CSS Transitions: Properties, Duration, Timing, and Delay

CSS Transitions

A CSS transition interpolates an animatable property between two computed states. Define the property, duration, timing function, and trigger state explicitly, then respect reduced-motion preferences.

CSS transitions let you animate a style change from one state to another. They are commonly used for hover effects, focus states, buttons, cards, menus, form feedback, theme changes, and small interface interactions. Without a transition, a style change happens instantly. With a transition, the browser smoothly moves between the old value and the new value over time.

Transitions are best when an element has two clear states, such as normal and hover, closed and open, hidden and visible, or inactive and active. If you need a multi-step sequence that runs automatically, use CSS animations with @keyframes instead.

Basic Syntax

A transition needs at least a property and a duration. The shorthand syntax is the most common way to write it.

When the button enters the :hover state, background-color changes from blue to darker blue over 200ms. When hover ends, it transitions back.

Basic Transition

Basic Transition
.button {
  background-color: #2563eb;
  color: white;
  padding: 10px 16px;
  border: none;
  border-radius: 6px;
  transition: background-color 200ms ease;
}

.button:hover {
  background-color: #1d4ed8;
}

Transition Properties

Property Purpose Example
transition-property Which CSS property should animate. opacity, transform, background-color
transition-duration How long the transition takes. 150ms, 0.3s
transition-timing-function How the speed changes during the transition. ease, linear, ease-out
transition-delay How long to wait before starting. 0ms, 100ms
transition Shorthand for all transition settings. opacity 200ms ease

Longhand vs Shorthand

The longhand properties are useful for learning and debugging. The shorthand is cleaner for production CSS.

Longhand and Shorthand

Longhand and Shorthand
/* Longhand */
.box {
  transition-property: opacity;
  transition-duration: 250ms;
  transition-timing-function: ease;
  transition-delay: 0ms;
}

/* Equivalent shorthand */
.box {
  transition: opacity 250ms ease 0ms;
}

Multiple Transitions

You can transition multiple properties by separating each transition with a comma. This lets each property have its own duration, timing function, and delay.

Multiple Properties

Multiple Properties
.card {
  opacity: 0.85;
  transform: translateY(0);
  box-shadow: 0 4px 12px rgba(15, 23, 42, 0.08);
  transition:
    opacity 180ms ease,
    transform 220ms ease,
    box-shadow 220ms ease;
}

.card:hover {
  opacity: 1;
  transform: translateY(-4px);
  box-shadow: 0 14px 30px rgba(15, 23, 42, 0.16);
}

Avoid transition: all

transition: all looks convenient, but it can animate properties you did not intend to animate. This can cause confusing bugs and performance problems. It is usually better to list the exact properties you want to transition.

Prefer Specific Properties

Prefer Specific Properties
/* Avoid in most production UI */
.panel {
  transition: all 300ms ease;
}

/* Better */
.panel {
  transition:
    opacity 200ms ease,
    transform 200ms ease;
}

Timing Functions

The timing function controls the speed curve. Two transitions can have the same duration but feel very different because of their timing function.

Timing function Behavior Best use
ease Starts slow, speeds up, ends slow. General UI transitions.
linear Same speed from start to end. Progress bars, continuous movement.
ease-in Starts slow, ends faster. Elements leaving the screen.
ease-out Starts faster, ends slow. Elements entering the screen.
ease-in-out Smooth start and smooth end. State changes and toggles.
cubic-bezier() Custom speed curve. Brand-specific or polished motion.

Custom Timing Curve

Custom Timing Curve
.drawer {
  transform: translateX(-100%);
  transition: transform 280ms cubic-bezier(0.22, 1, 0.36, 1);
}

.drawer.is-open {
  transform: translateX(0);
}

Transition Delay

A delay waits before the transition starts. Delays can be useful for staged UI effects, but use them carefully. Too many delays make an interface feel slow.

Transition Delay - CSS Example

Transition Delay - CSS Example
.tooltip {
  opacity: 0;
  transform: translateY(4px);
  transition:
    opacity 150ms ease 300ms,
    transform 150ms ease 300ms;
}

.button:hover .tooltip,
.button:focus-visible .tooltip {
  opacity: 1;
  transform: translateY(0);
}

Which Properties Transition Well?

For smooth UI motion, prefer properties that do not force the browser to recalculate layout on every frame. opacity and transform are usually the safest choices.

Better choices Use carefully
opacity width, height
transform top, left, right, bottom
background-color large box-shadow changes
color layout-heavy spacing changes

Button Hover and Focus Transition

Interactive controls should work for keyboard users too. Pair :hover with :focus-visible so the transition is not mouse-only.

Button Interaction

Button Interaction
.primary-button {
  background: #2563eb;
  color: #fff;
  border: 0;
  border-radius: 6px;
  padding: 10px 16px;
  transform: translateY(0);
  transition:
    background-color 160ms ease,
    transform 160ms ease,
    box-shadow 160ms ease;
}

.primary-button:hover,
.primary-button:focus-visible {
  background: #1d4ed8;
  transform: translateY(-2px);
  box-shadow: 0 8px 18px rgba(37, 99, 235, 0.28);
}

.primary-button:active {
  transform: translateY(0);
}

Card Hover Transition

Cards often use subtle transitions to show that they are clickable. Keep the movement small so the layout does not feel jumpy.

Card Hover

Card Hover
.course-card {
  border: 1px solid #e5e7eb;
  border-radius: 8px;
  padding: 18px;
  background: #fff;
  transform: translateY(0);
  transition:
    border-color 180ms ease,
    box-shadow 180ms ease,
    transform 180ms ease;
}

.course-card:hover {
  border-color: #93c5fd;
  box-shadow: 0 14px 34px rgba(15, 23, 42, 0.12);
  transform: translateY(-3px);
}

Fade and Slide Panel

A panel that appears and disappears can use opacity, transform, and visibility. This avoids animating display, which cannot transition between none and block.

Panel Transition

Panel Transition
.panel {
  opacity: 0;
  visibility: hidden;
  transform: translateY(8px);
  transition:
    opacity 180ms ease,
    transform 180ms ease,
    visibility 0s linear 180ms;
}

.panel.is-open {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
  transition:
    opacity 180ms ease,
    transform 180ms ease,
    visibility 0s;
}

Accordion Transition

Animating from height: 0 to height: auto does not work directly because auto is not an interpolable numeric value. A common CSS-only approach is to transition max-height with a known safe maximum.

For dynamic content with unknown height, JavaScript can measure the real height and set an exact pixel value. Pure CSS is simpler, but it needs a maximum height that fits the content.

Accordion

Accordion
.accordion-content {
  max-height: 0;
  overflow: hidden;
  opacity: 0;
  transition:
    max-height 260ms ease,
    opacity 180ms ease;
}

.accordion.is-open .accordion-content {
  max-height: 320px;
  opacity: 1;
}

Theme Transition

Transitions can make theme changes feel smoother. Keep them restrained so large page-wide transitions do not feel distracting.

Theme Change

Theme Change
:root {
  --page-bg: #ffffff;
  --text-color: #111827;
}

.dark-theme {
  --page-bg: #111827;
  --text-color: #f9fafb;
}

body {
  background: var(--page-bg);
  color: var(--text-color);
  transition:
    background-color 220ms ease,
    color 220ms ease;
}

Transitions with JavaScript

JavaScript often toggles a class, while CSS handles the visual transition. This keeps behavior and styling cleanly separated.

Class Toggle

Class Toggle
<button class="menu-button">Menu</button>
<nav class="menu">
  <a href="#">Home</a>
  <a href="#">Courses</a>
  <a href="#">Contact</a>
</nav>

Transitions with JavaScript - CSS Example

Transitions with JavaScript - CSS Example
.menu {
  opacity: 0;
  transform: translateY(-8px);
  pointer-events: none;
  transition: opacity 180ms ease, transform 180ms ease;
}

.menu.is-open {
  opacity: 1;
  transform: translateY(0);
  pointer-events: auto;
}

Transitions with JavaScript - JavaScript Example

Transitions with JavaScript - JavaScript Example
const button = document.querySelector('.menu-button');
const menu = document.querySelector('.menu');

button.addEventListener('click', () => {
  menu.classList.toggle('is-open');
});

transitionend Event

JavaScript can listen for the transitionend event when you need to run code after a transition finishes. This is useful for cleanup tasks after a panel closes or a toast disappears.

A transition can fire one transitionend event for each transitioned property, so check event.propertyName when needed.

transitionend

transitionend
const toast = document.querySelector('.toast');

toast.addEventListener('transitionend', event => {
  if (event.propertyName === 'opacity' && toast.classList.contains('is-hidden')) {
    toast.remove();
  }
});

Reduced Motion

Some users prefer less motion. Respect this with the prefers-reduced-motion media query. You can shorten or remove transitions while keeping the interface usable.

Reduced Motion - CSS Example

Reduced Motion - CSS Example
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    transition-duration: 1ms !important;
    transition-delay: 0ms !important;
    scroll-behavior: auto !important;
  }
}

Transitions vs Animations

Feature Transitions Animations
Trigger Needs a state change such as hover, focus, or class toggle. Can run automatically.
Steps Moves between two style states. Can define many keyframe steps.
Best for Buttons, menus, cards, simple UI feedback. Loaders, repeated motion, staged sequences.
CSS tool transition @keyframes and animation

Performance Best Practices

  • Prefer opacity and transform for smooth motion.
  • Avoid transitioning layout-heavy properties like width, height, top, and left when possible.
  • Use short durations for common interactions, usually 150ms to 300ms.
  • List exact transition properties instead of using all.
  • Test transitions on keyboard focus, not just mouse hover.
  • Respect prefers-reduced-motion.

Common Transition Problems

  • No transition runs: make sure the property has a different start and end value.
  • display does not animate: use opacity, visibility, or transforms instead.
  • height auto does not animate: use max-height or JavaScript-measured heights.
  • transition feels sluggish: reduce duration and avoid unnecessary delays.
  • layout jumps: prefer transform instead of changing actual layout position.

Summary

CSS transitions are ideal for smooth changes between two UI states. Use them for hover, focus, active, open, closed, visible, and hidden states. Choose specific properties, keep durations short, prefer opacity and transform, and respect reduced-motion preferences. For multi-step motion that runs independently, use CSS animations instead.

CSS Transitions Properties Duration Timing and Delay CSS fallback case

CSS Transitions Properties Duration Timing and Delay CSS fallback case
.lesson-box:empty::before {
  content: "CSS Transitions Properties Duration Timing and Delay: add visible content";
}
Before you move on

CSS Transitions: Properties, Duration, Timing, and Delay Mastery Check

5 checks
  • CSS transitions let you animate a style change from one state to another.
  • They are commonly used for hover effects, focus states, buttons, cards, menus, form feedback, theme changes, and small interface interactions.
  • Without a transition, a style change happens instantly.
  • With a transition, the browser smoothly moves between the old value and the new value over time.
  • Transitions are best when an element has two clear states, such as normal and hover, closed and open, hidden and visible, or inactive and active.

CSS Questions Learners Ask

A CSS transition smoothly animates a property from one value to another when an element changes state, such as hover, focus, active, or a class toggle.

No. <code>display</code> cannot smoothly transition between <code>none</code> and <code>block</code>. Use <code>opacity</code>, <code>visibility</code>, <code>transform</code>, or measured height techniques instead.

Most UI transitions feel good between <code>150ms</code> and <code>300ms</code>. Very small feedback can be faster, while larger panels may need slightly longer.

Browse Free Tutorials

Explore 500+ free tutorials across 20+ languages and frameworks.