Animation

CSS Transforms, Transitions & Animations

Making the Web Move

CSCI 4513 - Advanced Web Programming

Week 8, Lecture 16

Today's Learning Objectives

CSS Transforms

Changing Appearance Without Affecting Document Flow

Key Benefit: Transforms occur during composition phase

This makes them cheaper and more performant than many other CSS properties

Hardware Accelerated: Transforms can use the device's GPU for better performance

Transform Basics

The transform property takes CSS transform functions as values

.element {
  transform: rotate(45deg);
  transform: scale(1.5);
  transform: translate(100px, 50px);
}

⚠️ Cannot be applied to:

  • <col> and <colgroup>
  • Non-replaced inline elements (<span>, <b>, <em>)

2D Transforms: Rotate

.element {
  transform: rotate(45deg);
}

Original

Rotated

Positive values = clockwise, Negative values = counter-clockwise

2D Transforms: Scale

.element {
  transform: scaleX(1.5);  /* Scale width only */
  transform: scaleY(0.5);  /* Scale height only */
  transform: scale(2);     /* Scale both uniformly */
}

1x

1.5x

2D Transforms: Translate

.element {
  transform: translateX(50px);     /* Move right */
  transform: translateY(-30px);    /* Move up */
  transform: translate(50px, -30px); /* Both */
}

💡 Tip: Translate moves the element without affecting document flow

Unlike margin or position, other elements don't shift to fill the space

2D Transforms: Skew

.element {
  transform: skewX(20deg);  /* Skew horizontally */
  transform: skewY(10deg);  /* Skew vertically */
  transform: skew(20deg, 10deg); /* Both */
}

Original

Skewed

Chaining Multiple Transforms

Add multiple transform functions separated by spaces

.red-box {
  transform: rotate(45deg) translate(200%);
}

.blue-box {
  transform: translate(200%) rotate(45deg);
}

⚠️ Order Matters!

Transforms are applied from right to left

The red box translates first, then rotates around the origin

The blue box rotates in place, then translates

3D Transforms: Perspective

Sets the distance from the user to the z = 0 plane

.element {
  transform: perspective(500px) rotateY(45deg);
}

Critical Rule: perspective must be declared first (leftmost) when chaining transforms

Think of it like this: Perspective tells the browser "render as if we're viewing from this distance"

3D Rotate Functions

.element {
  transform: rotateX(45deg);  /* Rotate on X-axis */
  transform: rotateY(45deg);  /* Rotate on Y-axis */
  transform: rotateZ(45deg);  /* Same as rotate() */
  transform: rotate3d(1, 1, 0, 45deg); /* Custom axis */
}

Remember: Without perspective, 3D transforms won't look 3D!

Transform Performance

Why Transforms Are Fast

✅ Fast (Composite)

  • transform
  • opacity

⚠️ Slower (Paint/Layout)

  • background-color
  • width, height
  • margin, padding

Best Practice: Stick to transform and opacity for animations when performance matters

CSS Transitions

Smooth State Changes

Transitions animate changes from an element's initial state to an end state

button {
  background: white;
  transition: background-color 0.5s ease;
}

button:hover {
  background: black;
}

Transition Properties

button {
  transition-property: background-color;
  transition-duration: 1s;
  transition-timing-function: ease-out;
  transition-delay: 0.25s;
}

/* Shorthand */
button {
  transition: background-color 1s ease-out 0.25s;
}

transition-property: What CSS property to transition

transition-duration: How long the transition takes

transition-timing-function: Speed curve (ease, linear, ease-in, ease-out)

transition-delay: Delay before transition starts

Transition Triggers

Transitions require a trigger to start

CSS Triggers

  • :hover
  • :focus
  • :active
  • :checked

JavaScript Triggers

  • Adding a class
  • Removing a class
  • Toggling a class
// JavaScript trigger example
button.addEventListener('click', () => {
  dropdown.classList.add('open'); // Triggers transition
});

Stacking Context

The Z-Axis Layering System

Definition: 3D conceptualization of HTML elements along the z-axis (depth dimension)

z-index controls how far back or forward an element appears

But z-index only works within a stacking context!

Creating Stacking Contexts

Several CSS properties create new stacking contexts:

⚠️ Performance Impact: Multiple stacking contexts can cause repaints of all stacked elements during transitions

Nested Stacking Contexts

<article id="container3">  <!-- z-index: 4 -->
  <section id="container4">  <!-- z-index: 6 -->
  <section id="container5">  <!-- z-index: 1 -->
</article>

Think of z-index values as "version numbers":

  • Article #3 has z-index 4 → version 4.x
  • Section #4 has z-index 6 → version 4.6
  • Section #5 has z-index 1 → version 4.1

Section #5 (4.1) stacks above Section #4 (4.6) within their parent,
but Article #3 (4.x) as a whole stacks based on its parent's context!

Transition Performance Tips

✅ Do This

  • Transition transform
  • Transition opacity
  • Use will-change sparingly
  • Keep animations simple

⚠️ Avoid This

  • Transition width/height
  • Transition margin/padding
  • Too many stacking contexts
  • Complex background changes

Best Practice: Test transitions in browser DevTools performance tab

CSS Animations

Beyond Simple Transitions

Animations provide more control than transitions

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

.ball {
  animation: bounce 2s infinite;
}

Animations vs Transitions

Transitions

  • Simple A to B changes
  • Require a trigger
  • Less flexible
  • Can't loop (naturally)
  • Two states only

Animations

  • Complex multi-step changes
  • No trigger needed
  • Highly flexible
  • Designed for looping
  • Multiple keyframes

Use transitions for: Hover effects, focus states, simple state changes

Use animations for: Complex sequences, loading spinners, continuous effects

Animation Properties

.element {
  animation-name: slide-in;
  animation-duration: 2s;
  animation-timing-function: ease-in-out;
  animation-delay: 0.5s;
  animation-iteration-count: infinite;
  animation-direction: alternate;
  animation-fill-mode: forwards;
}

/* Shorthand */
.element {
  animation: slide-in 2s ease-in-out 0.5s infinite alternate forwards;
}

Animation Properties Explained

animation-name: References @keyframes name

animation-duration: How long one cycle takes

animation-timing-function: Speed curve (ease, linear, etc.)

animation-delay: Wait time before starting

animation-iteration-count: How many times (or infinite)

animation-direction: normal, reverse, alternate, alternate-reverse

animation-fill-mode: What happens before/after (forwards, backwards, both)

@keyframes At-Rule

Defines the animation sequence

@keyframes change-color {
  from {
    background-color: red;
  }

  to {
    background-color: green;
  }
}

/* Or use percentages */
@keyframes change-color {
  0% {
    background-color: red;
  }

  100% {
    background-color: green;
  }
}

from = 0% and to = 100%

Multiple Keyframes

@keyframes complex-animation {
  0% {
    transform: translateX(0) scale(1);
    background-color: red;
  }

  33% {
    transform: translateX(100px) scale(1.2);
    background-color: blue;
  }

  66% {
    transform: translateX(100px) rotate(180deg);
    background-color: green;
  }

  100% {
    transform: translateX(0) scale(1);
    background-color: red;
  }
}

You can define as many keyframes as you need at any percentage!

Animation Iteration Count

.element {
  animation: slide-in 2s;
  animation-iteration-count: 1; /* Runs once */
}

.loader {
  animation: spin 1s;
  animation-iteration-count: infinite; /* Loops forever */
}

.bounce {
  animation: bounce-up 0.5s;
  animation-iteration-count: 3; /* Runs 3 times */
}

Important: One iteration = one complete cycle from 0% to 100%

With alternate direction, it goes forward then backward

Animation Direction

normal: Plays forward (0% → 100%), then resets

reverse: Plays backward (100% → 0%), then resets

alternate: Forward, then backward, then forward...

alternate-reverse: Backward, then forward, then backward...

.smooth-bounce {
  animation: bounce 2s infinite alternate;
}

/* Plays forward for 2s, then backward for 2s, repeat */

Animation Fill Mode

none: Default - no styles applied before/after

forwards: Keeps the final keyframe styles after completion

backwards: Applies first keyframe styles during delay

both: Applies both forwards and backwards rules

.fade-in {
  opacity: 0;
  animation: fadeIn 1s forwards;
  /* Stays at opacity: 1 after animation */
}

@keyframes fadeIn {
  to { opacity: 1; }
}

Practical Animation Example

/* Loading spinner */
.spinner {
  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); }
}

When to Use What?

Use Transitions

  • Button hover effects
  • Menu open/close
  • Dropdown reveal
  • Color changes on :focus
  • Simple state changes

Use Animations

  • Loading spinners
  • Continuous effects
  • Multi-step sequences
  • Background animations
  • Complex entrance effects

Combining Transforms & Animations

.card {
  transition: transform 0.3s ease;
}

.card:hover {
  transform: translateY(-10px);
}

.card.loading {
  animation: pulse 1.5s ease-in-out infinite;
}

@keyframes pulse {
  0%, 100% { transform: scale(1); }
  50% { transform: scale(1.05); }
}

💡 Tip: You can use transitions for interactive states and animations for continuous effects on the same element!

CSS Triggers Reference

Different CSS properties trigger different browser operations:

Composite Only

transform, opacity

Paint + Composite

color, background

Layout + Paint + Composite

width, height, margin

Resource: Check csstriggers.com for detailed property information

Practice Exercise

Build These Common Patterns

1. Button Hover: Scale up 10% and change color on hover

2. Loading Spinner: Continuously rotating circle

3. Fade In: Element fades in from opacity 0 to 1

4. Slide In: Element slides in from left using transform

5. Bounce: Element bounces up and down infinitely

Challenge: Use only transform and opacity for best performance!

Assignment

The Odin Project - Animation

📖 Read: MDN - Using CSS Transitions

📖 Read: MDN - Using CSS Animations

📖 Read: Josh Comeau - The World of CSS Transforms

🔗 Explore: CSS Triggers website

💻 Complete: CSS Exercises - Animation folder

  • 01-button-hover
  • 02-pop-up
  • 03-dropdown-menu

Knowledge Check

❓ What are the four main 2D transform functions?

❓ How do you chain multiple transforms?

❓ What's required for 3D transforms to look 3D?

❓ What's the difference between transitions and animations?

❓ What does animation-iteration-count: infinite do?

❓ What are the most performant CSS properties to animate?

❓ What is stacking context and how is it created?

Today's Key Takeaways

Transforms change appearance without affecting document flow

Transitions animate simple state changes smoothly

Animations provide complex, multi-step sequences

Stacking context controls z-axis layering

Performance matters - use transform and opacity

@keyframes define animation sequences at percentages

Next Class

Responsive Design

📱 Media queries and breakpoints

🖥️ Mobile-first design

📐 Responsive units and layouts

🎨 Flexible images and typography

See you Thursday!