CSS Animation – How to Use Keyframes and steps() to Animate an Analog Alarm Clock - Part 1

Learn to animate an analog alarm clock using only CSS! Spin the clock hands and dynamically scale the clock body in this step-by-step article.

CSS Animation – How to Use Keyframes and steps() to Animate an Analog Alarm Clock - Part 1
Photo by Chirayu Trivedi / Unsplash

Introduction

A spinning hour and minute hand combined with a clock body that scales up creates a dynamic and visually appealing animation sequence.

In this two-part article series, you’ll learn how to animate an analog alarm clock using pure CSS:

  • Part 1 (this article): You’ll animate the hour hand, minute hand, and the clock body to bring the core structure of the clock to life.
  • Part 2: We’ll continue by animating the remaining parts—such as the clock feet, bells, hammer, and more—to complete the design with dynamic motion.

CSS properties and functions introduced in this article include:

  • steps()
  • @keyframes
  • animation
  • rotate
  • scale
  • CSS Custom Properties (Variables)

Preview

Analog Alarm Clock - Animation Preview
Analog Alarm Clock - Animation Preview

The Analog Alarm Clock was built using the following two-part article series.

CSS Art - How to Build a Pure CSS Analog Clock with Gradients & Variables - Part 1
Level up your front-end skills by building an analog clock from scratch. Master CSS Variables (Custom Properties) and Gradients in this step-by-step guide.
How to Build a Pure CSS Analog Clock with Gradients & Variables - Part 2
The clock is ticking—finish this iconic, timeless design using only CSS. Experiment with CSS properties and functions, let your creativity shine.

We recommend exploring these articles first—they provide the essential concepts and step-by-step guidance for creating the individual clock components. Understanding these foundations will make the animation implementation process much easier and more enjoyable.

Prerequisites

Essential CSS and HTML knowledge will help you understand the concepts and techniques introduced in this article. Jump over to this article if you require an HTML and CSS primer.

We assume you have configured tools to modify CSS. If not, this article will guide you through the setup process.

Please read this article if you’re unfamiliar with CSS animation and the @keyframes at-rule property.

HTML Structure

<div class="container">
  <div class="bell-tip"></div>
  <div class="left-bell"></div>
  <div class="right-bell"></div>
  <div class="bell-hammer"></div>
  <div class="clock-feet"></div>
  <div class="clock-body"></div>
  <div class="clock-face">
    <div class="number twelve">12</div>
    <div class="number three">3</div>
    <div class="number six">6</div>
    <div class="number nine">9</div>
  </div>
  <div class="hour-hand"></div>
  <div class="minute-hand"></div>
  <div class="dial"></div>
</div>

container is the outermost enclosure. It enables the content to be centered and draws a light gray border. The rest of the <div>s represent each animation sequence.

Keep the HTML structure as is for the animation to display correctly.

Body and Container <div> CSS

CSS code for the body and container <div>.

/* Body and Container Settings */
/* Center shapes */
body {
  margin: 0;
  padding: 0;
  height: 100vh;
  display: flex;
  justify-content: center;
  align-items: center;
  flex-wrap: wrap;
}

/* Set background and border color */
.container {
  width: 500px;
  height: 500px;
  border: 5px solid lightgray;
  background: transparent;
  position: relative;
  margin: 5px;
  display: flex;
  justify-content: center;
  align-items: center;
}

Animation Custom Variable

You’ll add the following custom variable to the :root pseudo-class.

This step ensures that your styles are globally accessible, making it easier to maintain and update your animation settings later.

/* Animation Setting */
:root {
  --animation-timing-function: ease-in-out;
}

The animation sequence uses the ease-in-out timing function. This means the animated properties start transitioning slowly, accelerate in the middle, and then slow down again toward the end. This creates a smooth and natural motion that feels more polished compared to linear transitions.

In the next section, we’ll focus on animating the Hour Hand.

Hour Hand

Now, let’s define the animation for the Hour Hand. We’ll use the animation property to apply a smooth, step-based movement that mimics the behavior of a real clock.

Hour Hand - Initial Position
Hour Hand - Initial Position
/* Clock Hands */
.hour-hand {
  animation: hour-hand 1.5s steps(12);
}
  • The animation name is set to hour-hand, which links this element to the corresponding @keyframes rule.
  • The duration is 1.5s, meaning the animation completes in one and a half seconds.
  • The steps(12) function ensures the Hour Hand moves in 12 discrete jumps—one for each hour—rather than sliding smoothly. This creates a realistic ticking effect.
Hour Hand - Two o’clock Position
Hour Hand - Two o’clock Position

The Hour Hand animation is designed to snap precisely to each clock hour during the sequence. This creates a realistic ticking effect, rather than a smooth continuous movement, which better mimics the behavior of a traditional analog clock.

Hour Hand - Three o’clock Position
Hour Hand - Three o’clock Position
@keyframes hour-hand {
  from {
    rotate: 0deg;
  }
  to {
    rotate: 360deg;
  }
}
  • @keyframes at-property hour-hand sets up the motion the element will follow during the animation.
  • The from and to define the start and end states—here, rotate: 0deg to rotate: 360deg for one full turn.
Hour Hand - Six o’clock Position
Hour Hand - Six o’clock Position
Hour Hand - Nine o’clock Position
Hour Hand - Nine o’clock Position

Great job! The Hour Hand animation sequence is now complete.

In the next section, we’ll move on to animating the Minute Hand. This step will add even more realism to your clock by creating smooth, precise movement for the minute indicator.

Minute Hand

Unlike the Hour Hand, the Minute Hand will move continuously throughout its animation sequence. This creates a smooth, flowing motion that closely mimics the behavior of a real analog clock, where the minute hand glides rather than jumps between positions.

Minute Hand - Initial Position
Minute Hand - Initial Position
.minute-hand {
  animation: minute-hand 1.5s var(--animation-timing-function);
}
  • minute-hand is the animation name that will link to our @keyframes definition.
  • 1.5s sets the duration of the animation.
  • var(--animation-timing-function) pulls in the timing function from a CSS variable, in this instance ease-in-out.
Minute Hand - Three o’clock Position
Minute Hand - 15 Minute Position
@keyframes minute-hand {
  from {
    rotate: 0deg;
  }
  to {
    rotate: -360deg;
  }
}
  • from is the starting point, and the Minute Hand is set to rotate: 0deg.
  • The to keyframe sets a full counterclockwise rotation using rotate: -360deg.
Minute Hand - Six o’clock Position
Minute Hand - 30 Minute Position

The Minute Hand will complete one entire sweep in the opposite direction of the default clockwise rotation, creating the smooth, continuous motion we want for an analog clock effect.

Minute Hand - Nine o’clock Position
Minute Hand - 45 Minute Position

With the Hour and Minute Hand animations complete, it’s time to bring the entire clock to life.

Up next, we’ll focus on animating the Clock Body. This step will add subtle motion and polish, making the overall design feel dynamic and visually appealing.

Clock Body

The Clock Body animation sequences combine two CSS properties:

  • scale
  • rotate
Clock Body - Scale Start
Clock Body - Scale Start

The Clock Body animation sequence starts with the element completely invisible and then gradually scales it up while rotating. This creates a smooth, eye-catching entrance effect that makes the animation feel dynamic and polished.

Clock Body - Continued Scale and Rotation
Clock Body - Continued Scale and Rotation
/* Clock Body */
.clock-body {
  animation: clock-body 1s var(--animation-timing-function);
}
  • clock-body is the animation name that will link to the @keyframes definition.
  • The animation length is set to 1s or one second.
  • The animation timing function is set to var(--animation-timing-function), which pulls in the timing function from a CSS variable, in this instance ease-in-out.
Clock Body - 70% Scaled and Rotated
Clock Body - 70% Scaled and Rotated
@keyframes clock-body {
  from {
    scale: 0;
    rotate: 180deg;
  }
  to {
    scale: 1;
    rotate: 0deg;
  }
}
  • The scale property controls the element’s size; 0 is fully collapsed, 1 is normal size.
  • The rotate property spins the element, starting at 180deg, or 180 degrees, adds a dramatic reveal as it rotates to 0deg.
Clock Body - Fully Scaled and Rotated
Clock Body - Fully Scaled and Rotated

You can see and play with the complete code on Pyxofy’s CodePen page.

See the Pen CSS Animation - How to Use Keyframes and steps() to Animate an Analog Alarm Clock by Pyxofy (@pyxofy) on CodePen.

Conclusion

In Part 1 of this two-part series, you learned how to animate the Hour Hand, Minute Hand, and Clock Body using only CSS.

  • You explored the steps() function to create a realistic, step-based animation for the Hour Hand.
  • You combined the CSS rotate, scale, and opacity properties to give the Clock Body a dynamic entrance effect.

In Part 2, we’ll take things further by animating the remaining elements of the analog clock. Until then, keep practicing and share your masterpiece with us on LinkedIn, Threads, Bluesky, Mastodon, X (Twitter) @pyxofy, or Facebook.

We hope you liked this article. Kindly share it with your network. We appreciate it.

CSS Animation – steps() Function Multi-Step Animation
Smooth animations are delightful to look at, but sometimes, you may want to control each keyframe with CSS. Learn how in this step-by-step article.
CSS Art – Hot Air Balloon
Is it a bird or a plane? It’s a hot air balloon! Learn with us how to make a colorful hot air balloon using CSS in this step-by-step article.
JavaScript - 背景色を変更する方法 - 配列からランダムに色を選ぶには?
JavaScript で要素のスタイルを変更する方法を学びましょう。ユーザーのクリックで背景色を変えるコードを、基本と応用に分けて解説します。プログラミング初心者の方や、配列や乱数について知りたい方におすすめの内容となっています。
Scratch(スクラッチ)とは? - 世界中でつかわれるプログラミングソフト
だれでも、じゆうに、かんたんに!Scratch(スクラッチ)をつかえば、あなたのアイデアを「プログラミング」で表現することができます。子どもも、大人も、初心者も。Scratchでプログラミングを体験してみましょう!