Esc

Try “tilt”, “reveal”, “drag”, or “reduced motion”.

← All examples

Gear train

Three meshed gears turn with the pointer. Spin values follow the gear ratio, so the teeth stay interlocked.

Move your pointer left and rightEdit
.gears {
  --k-motion: snappy;
  position: relative;
  height: 100%;
}

/* --r: pitch radius. --n: tooth count, proportional to the radius so the teeth line up. */
.gear {
  position: absolute;
  left: calc(50% + var(--x) - var(--r) - 5px);
  top: calc(50% + var(--y) - var(--r) - 5px);
  width: calc(var(--r) * 2 + 10px);
  height: calc(var(--r) * 2 + 10px);
  border-radius: 50%;
  background:
    radial-gradient(circle closest-side, #fff 0 22%, rgb(0 0 0 / 0.2) 23% 28%, transparent 29%),
    var(--gear);
  /* A body and a ring of teeth. --phase aligns the teeth with the next gear's gaps. */
  mask:
    radial-gradient(circle closest-side, #000 calc(100% - 10px), transparent calc(100% - 9.5px)),
    repeating-conic-gradient(from var(--phase), #000 0 calc(150deg / var(--n)), transparent 0 calc(360deg / var(--n)));
}

/* Spin is inversely proportional to the radius: 180 × 80 / 50 = 288, 288 × 50 / 35 = 411.43. */
.gear--large {
  --k-spin: 180deg;
  --gear: #1f2a44;
  --r: 80px;
  --n: 32;
  --phase: 6.41deg;
  --x: -71.2px;
  --y: 12.5px;
}

.gear--medium {
  --k-spin: -288deg;
  --gear: #2f6bff;
  --r: 50px;
  --n: 20;
  --phase: 16.25deg;
  --x: 46.6px;
  --y: -42.5px;
}

.gear--small {
  --k-spin: 411.43deg;
  --gear: #ff5d6c;
  --r: 35px;
  --n: 14;
  --phase: 25.36deg;
  --x: 116.2px;
  --y: 6.3px;
}

Uses