Zum Inhalt springen

A Deep Dive into CSS Animations with keyframes

You’ve mastered CSS hover effects and transitions to add that spark of interactivity to your sites. But what if you want to create more complex, multi-step animations that run without any user interaction? What if you want to make an element pulse, slide in, or shake on command?

For that, you need to unlock the power of CSS keyframes.

In this deep dive, we’ll go from the basic syntax to building three different, practical animations that you can use in your projects today.

What are @keyframes?

Think of keyframes as the director of your animation.

In a movie, the director sets key moments (frames) for an actor: „Start here, walk to the door, and then raise your hand.“ The actor then smoothly fills in the motion between those key points.

CSS @keyframes work the same way. You define the key styles at specific points during the animation timeline, and the browser handles the smooth transition between them.

The @keyframes rule is composed of two main parts:

  1. The Name: You give your animation a unique name, like slideInFromLeft or pulse. We’ll use this name later to apply the animation to an element.
  2. The Animation Timeline: You define the „stops“ or key moments of your animation. These can be defined using from and to for simple two-step animations, or with percentages (0%, 25%, 100%) for more complex sequences.

Here’s the basic structure:

@keyframes your-animation-name {
  from { /* CSS styles at the start (0%) */ }
  to { /* CSS styles at the end (100%) */ }
}

/* Or for more steps */
@keyframes another-animation-name {
  0% { /* Styles at the beginning */ }
  50% { /* Styles in the middle */ }
  100% { /* Styles at the end */ }
}

The animation Property: Bringing it to Life

Defining a @keyframes rule doesn’t do anything on its own. You need to apply it to an element using the animation property.

The animation property is a shorthand that combines several sub-properties:

  • animation-name: The name of your @keyframes rule.
  • animation-duration: How long the animation should take (e.g., 3s, 500ms).
  • animation-timing-function: The „speed curve“ of the animation (e.g., ease-in, linear, ease-in-out). This controls the acceleration and deceleration.
  • animation-delay: A pause before the animation starts (e.g., 1s).
  • animation-iteration-count: How many times to repeat the animation (e.g., 3, or infinite for non-stop).
  • animation-direction: The direction of the animation on repeat (e.g., normal, reverse, alternate). alternate is fantastic for looping animations, as it smoothly goes back and forth.
  • animation-fill-mode: What styles apply before the animation starts or after it ends (e.g., forwards to keep the styles from the last keyframe).

You can write them all out individually, but it’s cleaner to use the shorthand:

.my-element {
  /* animation: name duration timing-function delay iteration-count direction fill-mode; */
  animation: slideInFromLeft 1s ease-out 0s 1 normal forwards;
}

Now, let’s build something!

Example 1: The Pulsing Notification Dot

This is a classic UI element used to draw attention to something new. We want a dot that gently fades and scales up and down forever. This requires a from/to or 0%/100% sequence. Using alternate direction will make it look smooth and natural.

The HTML:

<div class="notification">
  <p>New Message</p>
  <div class="dot"></div>
</div>

The CSS:

/* First, let's define the animation itself */
@keyframes pulse {
  from {
    transform: scale(1);
    opacity: 1;
  }
  to {
    transform: scale(1.5);
    opacity: 0.5;
  }
}

/* Now, let's style the dot and apply the animation */
.dot {
  width: 10px;
  height: 10px;
  background-color: #ff4757; /* A bright red */
  border-radius: 50%;

  /* Apply the animation! */
  animation-name: pulse;
  animation-duration: 800ms;
  animation-iteration-count: infinite;
  animation-direction: alternate; /* This makes it go back and forth smoothly */
  animation-timing-function: ease-in-out;
}

/* Some basic styling for the container */
.notification {
  display: flex;
  align-items: center;
  gap: 10px;
  font-family: sans-serif;
}

Why this works: The pulse animation scales the dot from its normal size (scale(1)) to 1.5 times its size while also fading its opacity. Because we set the animation-direction to alternate, it plays forwards (100%) and then backwards (0%), creating a seamless, gentle throbbing effect.

Example 2: The „Shake on Error“ Input Field

Imagine a user enters the wrong password. A subtle shake is a great visual cue. We’ll use a multi-step keyframe to create a quick side-to-side wobble.

The HTML:

<input class="input-field" type="password" placeholder="Password">

We’ll add the .shake class with JavaScript when an error occurs, but for this demo, we’ll add it directly in the HTML.

<input class="input-field shake" type="password" placeholder="Password">

The CSS:

@keyframes shake {
  0% { transform: translateX(0); }
  25% { transform: translateX(-5px); } /* Move left */
  50% { transform: translateX(5px); }  /* Move right */
  75% { transform: translateX(-5px); } /* Move left */
  100% { transform: translateX(0); }
}

.input-field {
  padding: 10px;
  border: 2px solid #ccc;
  border-radius: 4px;
}

.input-field.shake {
  /* Apply the animation when the .shake class is present */
  animation: shake 400ms ease-in-out;
}

Why this works: We’ve defined keyframes at 0%, 25%, 50%, and 75% to create a back-and-forth motion with translateX. It starts at its original position, moves left, then right, then left again, and finally returns to the center. This all happens over a brisk 400 milliseconds, resulting in a sharp, noticeable shake.

Example 3: Slide-in Page Loader

Let’s make an elegant entry animation for an element, like a hero title or a section of content. We want it to slide in from the bottom and fade in at the same time.

Here, the animation-fill-mode: forwards property is crucial. It ensures the element stays at its final state (opacity: 1 and transform: translateY(0)) after the animation is done.

The HTML:

<h1 class="title">Welcome to the Page</h1>

The CSS:

@keyframes slideInFromBottom {
  from {
    opacity: 0;
    transform: translateY(50px); /* Start 50px below its final position */
  }
  to {
    opacity: 1;
    transform: translateY(0); /* End at its natural position */
  }
}

.title {
  font-family: sans-serif;
  font-size: 3rem;

  /* Start the element as invisible before the animation begins */
  opacity: 0;

  /*
    Shorthand: name duration timing-function fill-mode
  */
  animation: slideInFromBottom 1s ease-out forwards;
}

Why this works: The element starts off invisible (opacity: 0) and 50px below its final position. The animation then moves it up into place while simultaneously fading it in. The magic of forwards is that without it, the element would snap back to being invisible and 50px down after the animation finished. forwards tells it to hold the styles defined in the to keyframe.

Conclusion: Your Turn to Animate!

You’ve now seen how @keyframes and the animation property work together to create everything from subtle, infinite loops to sharp, one-off effects.

The key takeaways are:

  • Define with @keyframes: Give your animation a name and define the key style changes over a timeline using percentages.
  • Apply with animation: Use the animation shorthand property to assign your named animation to an element and control its duration, timing, and repetition.
  • Don’t forget the details: Properties like animation-direction: alternate; and animation-fill-mode: forwards; are the secret ingredients that can make an animation feel polished and professional.

The best way to learn is by doing. Try creating a fade-in animation, a spinning loader, or a bounce effect. Experiment with different timing functions and durations. The web is your playground! Happy animating.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert