CSStransition-duration & delay

transition-duration & transition-delay

transition-duration controls how long a CSS transition takes to complete. transition-delay controls when the transition starts after the property changes. Together, they fine-tune the timing of transitions. Duration ranges from 0s (instant) to 3s or more; delay can create staggered effects on multiple elements.

transition-duration basics

Property

Values

Purpose

transition-duration

Time (0s, 0.3s, 1s)

How long the transition takes

transition-delay

Time (0s, 0.2s, 0.5s)

Delay before transition starts

Both

Multiple durations/delays

For multiple properties

CSS
/* Single property with duration */
.button {
  background: #3498db;
  transition-property: background;
  transition-duration: 0.3s;
}

.button:hover {
  background: #2980b9;
}

/* Slow transition (1 second) */
.slow {
  transition-duration: 1s;
}

/* Very slow transition (2 seconds) */
.very-slow {
  transition-duration: 2s;
}

/* Fast transition (0.1 seconds) */
.fast {
  transition-duration: 0.1s;
}

/* Instant (0s) - no transition */
.instant {
  transition-duration: 0s;
}

/* Multiple properties with different durations */
.multi-prop {
  transition-property: background, transform, box-shadow;
  transition-duration: 0.3s, 0.5s, 0.2s;
  /* background: 0.3s, transform: 0.5s, shadow: 0.2s */
}

.multi-prop:hover {
  background: #2980b9;
  transform: scale(1.05);
  box-shadow: 0 4px 12px rgba(0,0,0,0.2);
}
transition-delay timing

CSS
/* Delay before transition starts */
.element {
  opacity: 0;
  transition-property: opacity;
  transition-duration: 0.5s;
  transition-delay: 0.2s;
  /* Waits 0.2s, then takes 0.5s to transition */
}

.element.visible {
  opacity: 1;
  /* Wait 0.2s, then fade in over 0.5s */
}

/* No delay (starts immediately) */
.no-delay {
  transition-duration: 0.3s;
  transition-delay: 0s;
}

/* Staggered animation with multiple elements */
.item {
  opacity: 0;
  transform: translateY(20px);
  transition-duration: 0.6s;
}

.item:nth-child(1) { transition-delay: 0s; }
.item:nth-child(2) { transition-delay: 0.1s; }
.item:nth-child(3) { transition-delay: 0.2s; }
.item:nth-child(4) { transition-delay: 0.3s; }

.item.visible {
  opacity: 1;
  transform: translateY(0);
  /* Each item staggered by 0.1s */
}

/* Negative delay (starts early) */
.negative-delay {
  transition-delay: -0.2s;
  /* Animation is 0.2s into progress when triggered */
}

/* Multiple properties with different delays */
.complex {
  transition-property: background, transform, opacity;
  transition-duration: 0.3s, 0.5s, 0.4s;
  transition-delay: 0s, 0.1s, 0.2s;
  /* background: no delay */
  /* transform: 0.1s delay */
  /* opacity: 0.2s delay */
}
Common duration patterns

CSS
/* Typical durations for different scenarios */

/* 0.1s - 0.2s: Micro-interactions (button press, checkbox) */
.micro-interaction {
  transition-duration: 0.15s;
}

/* 0.2s - 0.4s: Quick feedback (hover states, tooltips) */
.quick-feedback {
  transition-duration: 0.3s;
}

/* 0.5s - 0.8s: Medium animations (modal open, content reveal) */
.medium-animation {
  transition-duration: 0.6s;
}

/* 1s - 1.5s: Slow animations (page transitions, complex effects) */
.slow-animation {
  transition-duration: 1.2s;
}

/* 2s+: Very slow (background animations, continuous loops) */
.very-slow-animation {
  transition-duration: 2s;
}

/* Standard set of durations (use consistently) */
:root {
  --duration-fast: 0.15s;
  --duration-base: 0.3s;
  --duration-slow: 0.6s;
  --duration-very-slow: 1s;
}

.button {
  transition-duration: var(--duration-base);
}

.modal {
  transition-duration: var(--duration-slow);
}

.loading {
  transition-duration: var(--duration-very-slow);
}
Practical examples

CSS
/* Button with immediate color, delayed scale */
.button {
  background: #3498db;
  transform: scale(1);
  transition-property: background, transform;
  transition-duration: 0.2s, 0.3s;
  transition-delay: 0s, 0.05s;
  /* Color changes immediately, scale follows */
}

.button:hover {
  background: #2980b9;
  transform: scale(1.05);
}

/* Smooth dropdown menu reveal */
.dropdown {
  max-height: 0;
  overflow: hidden;
  opacity: 0;
  transition-property: max-height, opacity;
  transition-duration: 0.3s, 0.2s;
  transition-delay: 0s, 0.05s;
}

.dropdown.open {
  max-height: 500px;
  opacity: 1;
  /* max-height animates first, opacity fades in */
}

/* Card entrance animation with stagger */
.card {
  opacity: 0;
  transform: translateY(30px);
  transition-duration: 0.5s;
  transition-timing-function: ease-out;
}

.card:nth-child(1) { transition-delay: 0s; }
.card:nth-child(2) { transition-delay: 0.1s; }
.card:nth-child(3) { transition-delay: 0.2s; }
.card:nth-child(4) { transition-delay: 0.3s; }

.card.loaded {
  opacity: 1;
  transform: translateY(0);
  /* Cards slide up one by one */
}

/* Smooth theme transition */
:root[data-theme="dark"] {
  transition-duration: 0.3s;
  --color-bg: #1a1a1a;
  --color-text: #ffffff;
}

:root[data-theme="light"] {
  transition-duration: 0.3s;
  --color-bg: #ffffff;
  --color-text: #000000;
}

body {
  background-color: var(--color-bg);
  color: var(--color-text);
  transition-property: background-color, color;
  transition-duration: 0.3s;
}

/* Hover delay for tooltips */
.tooltip-trigger {
  position: relative;
}

.tooltip {
  position: absolute;
  opacity: 0;
  pointer-events: none;
  transition-duration: 0.2s;
  transition-delay: 0.5s;
  /* Only show on long hover (0.5s delay) */
}

.tooltip-trigger:hover .tooltip {
  opacity: 1;
  pointer-events: auto;
}
Performance considerations

CSS
/* Keep durations reasonable */

/* Too fast (less than 0.1s) */
.too-fast {
  transition-duration: 0.05s;
  /* May feel janky or instant */
}

/* Good range (0.15s - 1s) */
.good {
  transition-duration: 0.3s;
  /* Feels responsive and smooth */
}

/* Too slow (more than 2s) */
.too-slow {
  transition-duration: 3s;
  /* Feels sluggish and unresponsive */
}

/* Reduce motion for accessibility */
@media (prefers-reduced-motion: reduce) {
  * {
    transition-duration: 0.01s !important;
    animation-duration: 0.01s !important;
  }
}

/* Use GPU-accelerated properties for smooth transitions */
.smooth {
  transition-property: transform, opacity;
  /* These are GPU-accelerated */
  transition-duration: 0.3s;
}

.jittery {
  transition-property: width, height, padding;
  /* These cause reflows, less smooth */
  transition-duration: 0.3s;
}

/* Combine with will-change for performance */
.optimized {
  will-change: transform;
  transition-duration: 0.3s;
}
Note
`transition-duration` controls animation speed: typical values are 0.15s-0.3s for interactive feedback, 0.5s-0.8s for content reveals. `transition-delay` staggers animations: use 0.1s increments for list items. Together they control timing. Keep durations 0.15s-1s for best UX. Use CSS custom properties for consistency. Always respect `prefers-reduced-motion` media query for accessibility. Negative delays are possible but rare.
Next
Timing functions: [Timing Functions](/css/timing-functions).