25 CSS Spinners13 / 25

Pure CSSMIT licensed

Clock Tick Sweep Spinner

A precise gold second-hand sweeps in discrete tick steps around a minimal dark clock face with 12 hour markers, using CSS steps() timing to simulate mechanical tick motion.

Published

Live Demo
Try it

This is a full-page demo — interact inside the frame above, or open it in the playground for the full-screen experience.

The code

<div class="sp-13">
  <div class="sp-13__clock">
    <div class="sp-13__tick"></div>
    <div class="sp-13__tick"></div>
    <div class="sp-13__tick"></div>
    <div class="sp-13__tick"></div>
    <div class="sp-13__tick"></div>
    <div class="sp-13__tick"></div>
    <div class="sp-13__tick"></div>
    <div class="sp-13__tick"></div>
    <div class="sp-13__tick"></div>
    <div class="sp-13__tick"></div>
    <div class="sp-13__tick"></div>
    <div class="sp-13__tick"></div>
    <div class="sp-13__hand"></div>
    <div class="sp-13__center"></div>
  </div>
</div>
.sp-13,
.sp-13 *,
.sp-13 *::before,
.sp-13 *::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

.sp-13 {
  --bg: #0d0d0d;
  --face: #111;
  --ring: #e8e0d0;
  --hand: #f5c518;
  --tick: rgba(232,224,208,0.4);
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 100vh;
  background: var(--bg);
}

.sp-13__clock {
  position: relative;
  width: 80px;
  height: 80px;
  background: var(--face);
  border-radius: 50%;
  border: 2px solid var(--ring);
  box-shadow: 0 0 0 1px rgba(232,224,208,0.1),inset 0 0 16px rgba(0,0,0,0.5);
}

.sp-13__tick {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 2px;
  height: 6px;
  margin-left: -1px;
  background: var(--tick);
  transform-origin: bottom center;
  border-radius: 1px;
}

.sp-13__tick:nth-child(1) {
  transform: translateY(-100%) translateY(-27px) rotate(0deg);
}

.sp-13__tick:nth-child(2) {
  transform: translateY(-100%) translateY(-27px) rotate(30deg);
}

.sp-13__tick:nth-child(3) {
  transform: translateY(-100%) translateY(-27px) rotate(60deg);
}

.sp-13__tick:nth-child(4) {
  transform: translateY(-100%) translateY(-27px) rotate(90deg);
}

.sp-13__tick:nth-child(5) {
  transform: translateY(-100%) translateY(-27px) rotate(120deg);
}

.sp-13__tick:nth-child(6) {
  transform: translateY(-100%) translateY(-27px) rotate(150deg);
}

.sp-13__tick:nth-child(7) {
  transform: translateY(-100%) translateY(-27px) rotate(180deg);
}

.sp-13__tick:nth-child(8) {
  transform: translateY(-100%) translateY(-27px) rotate(210deg);
}

.sp-13__tick:nth-child(9) {
  transform: translateY(-100%) translateY(-27px) rotate(240deg);
}

.sp-13__tick:nth-child(10) {
  transform: translateY(-100%) translateY(-27px) rotate(270deg);
}

.sp-13__tick:nth-child(11) {
  transform: translateY(-100%) translateY(-27px) rotate(300deg);
}

.sp-13__tick:nth-child(12) {
  transform: translateY(-100%) translateY(-27px) rotate(330deg);
}

.sp-13__hand {
  position: absolute;
  bottom: 50%;
  left: 50%;
  width: 2px;
  height: 26px;
  margin-left: -1px;
  background: var(--hand);
  border-radius: 2px 2px 0 0;
  transform-origin: bottom center;
  box-shadow: 0 0 4px var(--hand);
  animation: sp-13-tick 1s steps(60,end) infinite;
}

.sp-13__center {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--hand);
  transform: translate(-50%,-50%);
  box-shadow: 0 0 4px var(--hand);
}

@keyframes sp-13-tick {
  to {
    transform: rotate(360deg);
  }
}

@media (prefers-reduced-motion: reduce) {
  .sp-13__hand {
    animation: none;
  }
}
Paste this into ChatGPT, Claude, Cursor, or any coding assistant. The block below is pre-framed with everything the AI needs to integrate this demo into your project — markup, styles, scoping notes, and the source URL. Hit Copy and paste straight into your chat.
Here's a working CSS Spinner from CodeFronts. Use it as-is or adapt to your framework. All classes are scoped under a unique prefix so the code won't collide with your existing styles. MIT licensed.
Demo: Clock Tick Sweep Spinner
Source: https://codefronts.com/motion/css-spinner-designs/clock-tick-sweep-spinner/

A precise gold second-hand sweeps in discrete tick steps around a minimal dark clock face with 12 hour markers, using CSS steps() timing to simulate mechanical tick motion.
## HTML
```html
<div class="sp-13">
  <div class="sp-13__clock">
    <div class="sp-13__tick"></div>
    <div class="sp-13__tick"></div>
    <div class="sp-13__tick"></div>
    <div class="sp-13__tick"></div>
    <div class="sp-13__tick"></div>
    <div class="sp-13__tick"></div>
    <div class="sp-13__tick"></div>
    <div class="sp-13__tick"></div>
    <div class="sp-13__tick"></div>
    <div class="sp-13__tick"></div>
    <div class="sp-13__tick"></div>
    <div class="sp-13__tick"></div>
    <div class="sp-13__hand"></div>
    <div class="sp-13__center"></div>
  </div>
</div>
```
## CSS
```css
.sp-13,
.sp-13 *,
.sp-13 *::before,
.sp-13 *::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

.sp-13 {
  --bg: #0d0d0d;
  --face: #111;
  --ring: #e8e0d0;
  --hand: #f5c518;
  --tick: rgba(232,224,208,0.4);
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 100vh;
  background: var(--bg);
}

.sp-13__clock {
  position: relative;
  width: 80px;
  height: 80px;
  background: var(--face);
  border-radius: 50%;
  border: 2px solid var(--ring);
  box-shadow: 0 0 0 1px rgba(232,224,208,0.1),inset 0 0 16px rgba(0,0,0,0.5);
}

.sp-13__tick {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 2px;
  height: 6px;
  margin-left: -1px;
  background: var(--tick);
  transform-origin: bottom center;
  border-radius: 1px;
}

.sp-13__tick:nth-child(1) {
  transform: translateY(-100%) translateY(-27px) rotate(0deg);
}

.sp-13__tick:nth-child(2) {
  transform: translateY(-100%) translateY(-27px) rotate(30deg);
}

.sp-13__tick:nth-child(3) {
  transform: translateY(-100%) translateY(-27px) rotate(60deg);
}

.sp-13__tick:nth-child(4) {
  transform: translateY(-100%) translateY(-27px) rotate(90deg);
}

.sp-13__tick:nth-child(5) {
  transform: translateY(-100%) translateY(-27px) rotate(120deg);
}

.sp-13__tick:nth-child(6) {
  transform: translateY(-100%) translateY(-27px) rotate(150deg);
}

.sp-13__tick:nth-child(7) {
  transform: translateY(-100%) translateY(-27px) rotate(180deg);
}

.sp-13__tick:nth-child(8) {
  transform: translateY(-100%) translateY(-27px) rotate(210deg);
}

.sp-13__tick:nth-child(9) {
  transform: translateY(-100%) translateY(-27px) rotate(240deg);
}

.sp-13__tick:nth-child(10) {
  transform: translateY(-100%) translateY(-27px) rotate(270deg);
}

.sp-13__tick:nth-child(11) {
  transform: translateY(-100%) translateY(-27px) rotate(300deg);
}

.sp-13__tick:nth-child(12) {
  transform: translateY(-100%) translateY(-27px) rotate(330deg);
}

.sp-13__hand {
  position: absolute;
  bottom: 50%;
  left: 50%;
  width: 2px;
  height: 26px;
  margin-left: -1px;
  background: var(--hand);
  border-radius: 2px 2px 0 0;
  transform-origin: bottom center;
  box-shadow: 0 0 4px var(--hand);
  animation: sp-13-tick 1s steps(60,end) infinite;
}

.sp-13__center {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--hand);
  transform: translate(-50%,-50%);
  box-shadow: 0 0 4px var(--hand);
}

@keyframes sp-13-tick {
  to {
    transform: rotate(360deg);
  }
}

@media (prefers-reduced-motion: reduce) {
  .sp-13__hand {
    animation: none;
  }
}
```

How this works

The clock face is a circle styled with a dark background and a subtle inset shadow for depth, with 12 small tick marks positioned using the same radial offset technique as clock hands — each tick is a thin rectangle placed at top:50%;left:50%, rotated by N×30deg, then translated outward. The 12 individual nth-child rules pre-rotate each tick to its hour position.

The hand element uses bottom:50% (so it grows upward from the pivot) with transform-origin:bottom center. Its animation uses steps(60, end) timing — this makes the hand snap to each of 60 discrete positions per revolution rather than smoothly easing, exactly replicating the tick-tick motion of a mechanical clock second hand.

Make it yours

  • Change the hand colour via --hand — a red (#e53935) hand on a white face creates a classic kitchen-timer look.
  • Add a minute hand by duplicating the hand element with a longer duration (60s) and a different colour.
  • Replace steps(60,end) with linear for a smooth sweep hand (quartz vs mechanical analogy).
  • Increase tick mark height from 6px to 10px and add a larger square every 3rd tick using nth-child(3n) for a more detailed clock face.
  • Wrap in a larger outer bezel div with a metallic background:conic-gradient(...) for a watch-case appearance.

Gotchas — read before shipping

  • steps(60,end) produces 60 positions per full rotation — for a spinner rather than a clock, steps(8,end) or steps(12,end) gives a crisper mechanical feel without requiring a full second-hand metaphor.
  • The tick marks use a specific translate distance tuned to the 80px wrapper — resizing the clock requires recalculating the translateY(-27px) offset to keep ticks inside the ring.
  • Using bottom:50% instead of top:50% for the hand positioning means the pivot point is at the visual centre — changing to top:50% and adjusting height will invert the hand direction.

Browser support

ChromeSafariFirefoxEdge
60+12+60+60+

steps() timing function well-supported; no modern-only APIs needed.

Techniques used in this demo

Search CodeFronts

Loading…