CSS Animations: Theory & Interactive Examples

What are CSS Animations?

CSS animations allow you to animate the values of CSS properties over time using @keyframes. Unlike transitions, which animate between two states, animations can define multiple steps and run automatically, loop, or alternate direction.

Animation Properties

Shorthand: animation: name duration timing-function delay iteration-count direction fill-mode;
Example: animation: bounce 1s ease-in-out 0.2s infinite alternate;

@keyframes

Define the animation steps using @keyframes:

@keyframes bounce {
  0%   { transform: translateY(0); }
  50%  { transform: translateY(-40px); }
  100% { transform: translateY(0); }
}

How CSS Animations Work

CSS animations use @keyframes to define multiple steps of an animation, allowing for complex, multi-stage effects. Animations can run automatically, loop, alternate, or be triggered by user interaction. Unlike transitions, which only animate between two states, animations can have as many steps as you want.

Animation Lifecycle

  1. Start State: The element's initial style.
  2. Keyframes: Define the intermediate and end states.
  3. Animation Properties: Control timing, repetition, direction, and more.
  4. End State: Determined by animation-fill-mode and keyframes.

Common Use Cases

Interactive Examples

1. Basic Animation

Bounce!
@keyframes bounce {
  0%   { transform: translateY(0); }
  50%  { transform: translateY(-40px); }
  100% { transform: translateY(0); }
}
.anim-bounce {
  animation: bounce 1s ease-in-out infinite;
}

2. Animation Delay

Wait for it...
@keyframes fadeIn {
  from { opacity: 0; }
  to   { opacity: 1; }
}
.anim-delay {
  animation: fadeIn 1.2s ease 1s forwards;
}

3. Iteration Count

3x Loop
@keyframes colorLoop {
  0%   { background: #3498db; }
  50%  { background: #8e44ad; }
  100% { background: #3498db; }
}
.anim-iterate {
  animation: colorLoop 1.2s linear 0s 3;
}

4. Animation Direction

Alternate
@keyframes slideX {
  from { transform: translateX(0); }
  to   { transform: translateX(60px); }
}
.anim-direction {
  animation: slideX 1.1s cubic-bezier(.4,1.6,.4,1) infinite alternate;
}

5. Fill Mode

Stay!
@keyframes grow {
  from { width: 120px; }
  to   { width: 220px; }
}
.anim-fill {
  animation: grow 1.2s ease-in 0s 1 forwards;
}

6. Multiple Animations

Combo
@keyframes spin {
  to { transform: rotate(360deg); }
}
@keyframes pulse {
  0%, 100% { box-shadow: 0 0 0 0 #8e44ad44; }
  50% { box-shadow: 0 0 16px 8px #8e44ad44; }
}
.anim-multi {
  animation: spin 1.2s linear infinite, pulse 1.2s ease-in-out infinite;
}

7. Image Animation

Image of a man playing with fire
@keyframes imgPop {
  0%   { transform: scale(1) rotate(0deg); }
  50%  { transform: scale(1.13) rotate(-4deg); }
  100% { transform: scale(1) rotate(0deg); }
}
.img-anim-demo {
  animation: imgPop 1.4s cubic-bezier(.4,1.6,.4,1) infinite;
}

8. Pendulum Animation (Real-World Example)

@keyframes swing {
  0%   { transform: rotate(-30deg); }
  50%  { transform: rotate(30deg); }
  100% { transform: rotate(-30deg); }
}
.pendulum-arm {
  width: 6px;
  height: 90px;
  background: #8e44ad;
  margin: 0 auto;
  border-radius: 3px;
  transform-origin: top center;
  animation: swing 2s cubic-bezier(.4,1.6,.4,1) infinite;
}
.pendulum-bob {
  width: 32px;
  height: 32px;
  background: #ffd200;
  border-radius: 50%;
  box-shadow: 0 4px 16px #8e44ad44;
  border: 3px solid #8e44ad;
  position: absolute;
  bottom: -16px;
  left: 50%;
  transform: translateX(-50%);
}

9. Loader Dots

@keyframes dotFlare {
  0%, 80%, 100% { opacity: 0.3; }
  40% { opacity: 1; }
}
.dot {
  display: inline-block;
  width: 14px;
  height: 14px;
  margin: 0 4px;
  background: #3498db;
  border-radius: 50%;
  animation: dotFlare 1.2s infinite both;
}
.dot2 { animation-delay: 0.2s; }
.dot3 { animation-delay: 0.4s; }

10. Card Flip (Hover)

Front
Back
.flip-card {
  width: 120px;
  height: 60px;
  perspective: 600px;
}
.flip-inner {
  width: 100%;
  height: 100%;
  transition: transform 0.7s cubic-bezier(.4,1.6,.4,1);
  transform-style: preserve-3d;
  position: relative;
}
.flip-card:hover .flip-inner {
  transform: rotateY(180deg);
}
.flip-front, .flip-back {
  position: absolute;
  width: 100%;
  height: 100%;
  backface-visibility: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 600;
  font-size: 1.1rem;
  border-radius: 8px;
}
.flip-front {
  background: #3498db;
  color: #fff;
}
.flip-back {
  background: #ffd200;
  color: #222;
  transform: rotateY(180deg);
}

Tip: Watch the pendulum swing, loader dots pulse, and flip the card by hovering! Real-world and UI animation patterns are easy with CSS.

Best Practices & Notes

Further Exploration