CSS Animations and Transitions Guide

CSS provides two primary ways to animate elements: transitions and animations. Transitions allow simple animations between property states, while animations enable more complex, keyframe-based sequences. This guide covers both approaches in depth.

1. CSS Transitions

Transitions provide a way to smoothly change from one property value to another over a specified duration. They're ideal for simple state changes like hover effects.

Basic Transition Syntax

/* Basic syntax */
.element {
  transition: property duration timing-function delay;
}

/* Example */
.element {
  transition: background-color 0.5s ease 0s;
}

Transition Properties

background-color transition
Hover Me
.transition-color:hover {
  background-color: #e74c3c;
  transition: background-color 0.5s ease;
}
transform transition
Hover Me
.transition-transform:hover {
  transform: scale(1.2) rotate(10deg);
  transition: transform 0.5s ease;
}
Multiple property transition
Hover Me
.transition-multiple:hover {
  background-color: #2ecc71;
  transform: translateY(-10px);
  box-shadow: 0 10px 20px rgba(0,0,0,0.2);
  transition: all 0.5s ease;
}
Transition delay
Hover Me
.transition-delay:hover {
  background-color: #e74c3c;
  transition: background-color 0.5s ease 0.2s;
}

Timing Functions

Timing functions control the pace of the transition over its duration.

linear
Hover Me
transition: transform 1s linear;

Constant speed from start to finish.

ease (default)
Hover Me
transition: transform 1s ease;

Slow start, fast middle, slow end.

ease-in
Hover Me
transition: transform 1s ease-in;

Slow start, fast end.

ease-out
Hover Me
transition: transform 1s ease-out;

Fast start, slow end.

ease-in-out
Hover Me
transition: transform 1s ease-in-out;

Slow start and end, fast middle.

cubic-bezier()
Hover Me
transition: transform 1s cubic-bezier(0.68, -0.55, 0.27, 1.55);

Custom timing function with bounce effect.

Transition Individual Properties

/* Individual transition properties */
.element {
  transition-property: transform, background-color;
  transition-duration: 0.5s, 1s;
  transition-timing-function: ease, linear;
  transition-delay: 0s, 0.2s;
}

Animatable Properties

Not all CSS properties can be transitioned. Here are common animatable properties:

2. CSS Animations

CSS animations provide more control than transitions, allowing multiple states and more complex sequences through keyframes.

Basic Animation Syntax

/* Define the keyframes */
@keyframes animation-name {
  from {
    /* CSS properties at start */
  }
  to {
    /* CSS properties at end */
  }
}

/* Apply the animation */
.element {
  animation: animation-name duration timing-function delay iteration-count direction fill-mode play-state;
}

Simple Animation Examples

Bounce Animation
Bounce
.animation-bounce {
  animation: bounce 1s infinite alternate;
}

@keyframes bounce {
  from {
    transform: translateY(0);
  }
  to {
    transform: translateY(-20px);
  }
}
Rotate Animation
Rotate
.animation-rotate {
  animation: rotate 2s linear infinite;
}

@keyframes rotate {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
}
Pulse Animation
Pulse
.animation-pulse {
  animation: pulse 1.5s ease-in-out infinite;
}

@keyframes pulse {
  0% {
    transform: scale(1);
  }
  50% {
    transform: scale(1.1);
  }
  100% {
    transform: scale(1);
  }
}
Fade Animation
Fade
.animation-fade {
  animation: fade 2s ease-in-out infinite;
}

@keyframes fade {
  0% {
    opacity: 1;
  }
  50% {
    opacity: 0.5;
  }
  100% {
    opacity: 1;
  }
}
Shake Animation
Shake
.animation-shake {
  animation: shake 0.5s ease-in-out infinite;
}

@keyframes shake {
  0%, 100% {
    transform: translateX(0);
  }
  25% {
    transform: translateX(-10px);
  }
  75% {
    transform: translateX(10px);
  }
}
Slide Animation
Slide
.animation-slide {
  animation: slide 2s ease infinite;
}

@keyframes slide {
  0% {
    transform: translateX(-100%);
  }
  50% {
    transform: translateX(50px);
  }
  100% {
    transform: translateX(-100%);
  }
}
Color Change
Colors
.animation-colors {
  animation: colors 3s linear infinite;
}

@keyframes colors {
  0% {
    background-color: #3498db;
  }
  25% {
    background-color: #2ecc71;
  }
  50% {
    background-color: #f1c40f;
  }
  75% {
    background-color: #e74c3c;
  }
  100% {
    background-color: #3498db;
  }
}
Combined Animation
Combo
.animation-combo {
  animation: combo 3s ease infinite;
}

@keyframes combo {
  0% {
    transform: translateX(0) scale(1);
    background-color: #3498db;
  }
  25% {
    transform: translateX(50px) scale(1.1);
    background-color: #2ecc71;
  }
  50% {
    transform: translateX(0) scale(1);
    background-color: #f1c40f;
  }
  75% {
    transform: translateX(-50px) scale(1.1);
    background-color: #e74c3c;
  }
  100% {
    transform: translateX(0) scale(1);
    background-color: #3498db;
  }
}

Animation Properties

These properties give you fine-grained control over your animations:

animation-duration
Duration
.element {
  animation-duration: 1s;
}

Specifies how long the animation takes to complete one cycle.

animation-timing-function
Timing
.element {
  animation-timing-function: ease-in-out;
}

Controls the pace of the animation (same options as transitions).

animation-delay
Delay
.element {
  animation-delay: 1s;
}

Specifies a delay before the animation starts.

animation-iteration-count
3 Times
.element {
  animation-iteration-count: 3; /* or infinite */
}

Specifies how many times the animation should run.

animation-direction
Direction
.element {
  animation-direction: alternate; 
  /* normal | reverse | alternate | alternate-reverse */
}

Controls whether the animation plays forwards, backwards, or alternates.

animation-fill-mode: forwards
Forwards
.element {
  animation-fill-mode: forwards;
  /* none | forwards | backwards | both */
}

Element retains styles from the last keyframe after animation ends.

animation-fill-mode: backwards
Backwards
.element {
  animation-fill-mode: backwards;
}

Element applies the first keyframe styles during delay period.

animation-play-state
Hover to Pause
.element {
  animation-play-state: running; /* or paused */
}

.element:hover {
  animation-play-state: paused;
}

Advanced Keyframe Techniques

/* Using percentages for more control */
@keyframes fadeInOut {
  0% {
    opacity: 0;
  }
  25% {
    opacity: 1;
  }
  75% {
    opacity: 1;
  }
  100% {
    opacity: 0;
  }
}

Steps() Timing Function

Steps Animation
.anim-steps {
  animation: steps 4s steps(4) infinite;
}

@keyframes steps {
  0% {
    left: 0;
  }
  100% {
    left: calc(100% - 20px);
  }
}

The steps() function creates a discrete, frame-by-frame animation instead of a smooth transition.

Staggered Animations

Staggered Loading
.staggered-item {
  animation: bounce 0.5s infinite alternate;
}

.staggered-item:nth-child(2) {
  animation-delay: 0.1s;
}

.staggered-item:nth-child(3) {
  animation-delay: 0.2s;
}

/* And so on... */

3. Practical Examples

Loading Spinner

.loader {
  width: 50px;
  height: 50px;
  border: 5px solid #f3f3f3;
  border-top: 5px solid #3498db;
  border-radius: 50%;
  animation: spin 1s linear infinite;
}

@keyframes spin {
  0% {
    transform: rotate(0deg);
  }
  100% {
    transform: rotate(360deg);
  }
}

Content Placeholder/Skeleton Screen

.placeholder {
  width: 300px;
  height: 30px;
  background: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
  background-size: 200% 100%;
  animation: shimmer 1.5s infinite;
  border-radius: 4px;
}

@keyframes shimmer {
  0% {
    background-position: -100% 0;
  }
  100% {
    background-position: 100% 0;
  }
}

Notification Alert

Success Message
.notification {
  padding: 10px 15px;
  background-color: #2ecc71;
  color: white;
  border-radius: 4px;
  animation: slideDown 0.5s ease forwards;
  transform: translateY(-100%);
}

@keyframes slideDown {
  to {
    transform: translateY(0);
  }
}

Attention-Grabbing Button

.btn-pulse {
  padding: 10px 20px;
  background-color: #3498db;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  animation: buttonPulse 2s infinite;
}

@keyframes buttonPulse {
  0% {
    box-shadow: 0 0 0 0 rgba(52, 152, 219, 0.7);
  }
  70% {
    box-shadow: 0 0 0 10px rgba(52, 152, 219, 0);
  }
  100% {
    box-shadow: 0 0 0 0 rgba(52, 152, 219, 0);
  }
}

4. Advanced Techniques

Adding/Removing Animations with JavaScript

// HTML
<div class="click-animate" id="clickBox"></div>
<button onclick="animateElement()">Animate</button>

// CSS
.bounce-animation {
  animation: bounce 1s;
}

// JavaScript
function animateElement() {
  const element = document.getElementById('clickBox');
  element.classList.remove('bounce-animation');
  
  // Trigger reflow
  void element.offsetWidth;
  
  element.classList.add('bounce-animation');
}

CSS Animation Events

const element = document.getElementById('animatedElement');

element.addEventListener('animationstart', () => {
  console.log('Animation started');
});

element.addEventListener('animationend', () => {
  console.log('Animation ended');
});

element.addEventListener('animationiteration', () => {
  console.log('Animation iteration');
});

Accessibility Considerations

Respects preference
/* Respect user's motion preferences */
@media (prefers-reduced-motion: reduce) {
  .respects-motion-preference {
    animation: none;
    transition: none;
  }
}

Be considerate of users who may be sensitive to motion or have vestibular disorders by respecting the 'prefers-reduced-motion' media query.

Animation Performance Tips

5. When to Use Transitions vs. Animations

Use Transitions When:

Use Animations When:

6. Browser Support and Prefixes

Modern browsers have excellent support for CSS transitions and animations. However, for older browsers, you might need vendor prefixes:

/* Prefixed transitions (for older browsers) */
.element {
  -webkit-transition: all 0.5s ease;
  -moz-transition: all 0.5s ease;
  -o-transition: all 0.5s ease;
  transition: all 0.5s ease;
}

/* Prefixed animations (for older browsers) */
@-webkit-keyframes fadeIn { /* ... */ }
@-moz-keyframes fadeIn { /* ... */ }
@-o-keyframes fadeIn { /* ... */ }
@keyframes fadeIn { /* ... */ }

.element {
  -webkit-animation: fadeIn 1s;
  -moz-animation: fadeIn 1s;
  -o-animation: fadeIn 1s;
  animation: fadeIn 1s;
}

Modern development typically uses build tools like Autoprefixer to handle these prefixes automatically.