Design with Code

Exercise 17

Animate Your Interface

Add life to your weather app with CSS transitions and keyframe animations

What you'll learn

Key takeaways from this exercise

  • Adding smooth transitions for hover effects with Tailwind
  • Using Tailwind's built-in animations like animate-pulse
  • Creating custom keyframe animations with CSS
  • Controlling animation timing with CSS variables
  • Enabling and disabling animations conditionally with the group pattern

Introduction

Your weather app has gradients, shadows, custom SVG icons, and dynamic backgrounds. Everything looks polished — but it's static. Nothing moves. Adding motion brings personality and life to an interface. Subtle animations make an app feel responsive and crafted, turning something that works into something that delights.

Transitions vs animations

There are two main categories of motion in CSS, and understanding the difference helps you pick the right tool. A transition creates a smooth change between two states — when you hover over a card, a color fades, an element scales up, an opacity changes. Transitions are reactive: they respond to a state change (like hover or focus). An animation, on the other hand, is self-running — it plays on its own, continuously or for a set number of cycles, without needing a trigger.

Tailwind transitions

Tailwind makes transitions easy with transition-* utilities. Adding transition-opacity duration-150 to an element means any change to its opacity will animate smoothly over 150 milliseconds instead of snapping instantly. Duration classes (duration-75, duration-150, duration-300, etc.) control how long the transition takes. Shorter durations feel snappier; longer ones feel smoother. For interactive elements like cards and buttons, duration-150 is usually a good starting point.

Keyframe animations

For keyframe animations — the self-running kind — you define the motion in CSS using @keyframes. A keyframe animation specifies what the element should look like at different points in time: at 0%, at 50%, at 100%. The browser smoothly interpolates between these states. The timing function controls the acceleration pattern: ease-in-out starts and ends slowly with speed in the middle, linear moves at a constant rate, ease-out starts fast and decelerates. Timing functions are one of those things that designers intuitively understand — you know when motion feels right or wrong, even if you can't name the exact curve.

Built-in Tailwind animations

Tailwind provides several built-in animations you can use immediately: animate-pulse (a gentle opacity/scale pulsing, great for loading states), animate-spin (continuous rotation), animate-ping (a ripple effect), and animate-bounce (bouncing motion). These are applied as a single class — no custom CSS needed.

Custom animations

For custom motion, like making clouds gently float side to side in your weather icons, you define your own keyframes and animation classes. A useful pattern is to use CSS variables for animation duration and delay. This lets parent elements control their children's animation behavior: set --animation-duration: 0 to pause an animation, or --animation-duration: 4s to play it. The group and group-hover: pattern in Tailwind makes this especially powerful — you can make an icon animate only when its parent card is hovered.

Animation delays create staggered effects. If multiple clouds use the same animation, they'll move in perfect sync — which looks mechanical. By giving each cloud a different delay (even a negative delay, which starts the animation mid-cycle), you create natural, organic-feeling motion where elements move independently.

Beyond CSS

For more complex animations than CSS can handle, JavaScript animation libraries like Framer Motion and GSAP exist. Framer Motion is popular in the React ecosystem for declarative, component-level animations. GSAP is a professional-grade library for complex timelines and physics-based motion. You don't need to learn these now, but knowing they exist helps you recognize them in codebases and know when to reach for them.

Motion is a core design skill, and this exercise connects that skill directly to code. You already have opinions about timing, easing, and choreography — you've been making these decisions in design tools for years. Now you can express those opinions in the actual medium. When AI generates an animation with linear timing, you can tell it to use ease-out instead — and know exactly why it matters.

Create a free account to access the full course

In order to access full course content and track your progress, please sign in