Digital Garden

Between Light and Dark: a Theme Toggle the iPhone Way

2026-09-14 · ~2 min read · design · iteration log

Before: a toggle with no ceremony

The theme button always cycled through three states: auto → light → dark. Icons flipped instantly, the page snapped. The feature was complete, but that “snap” felt like a light switch, not a sunset.

How the iPhone does it

iOS never “snaps” when the theme changes. Three layers happen at once:

  1. The icon springs in — the new icon arrives from 0.4× scale and -100° rotation, straightening along the system spring curve. The old one isn’t deleted; it’s replaced by the one being rotated out
  2. The button rebounds — at the instant of the tap it compresses to 0.86 and springs back; the fingertip knows before the eyes that “I hit it”
  3. The whole page cross-fades — the View Transitions API captures old and new frames, cross-dissolving over 0.5 seconds. Not a skin change; the whole world changes its light together

A latch

One detail almost ruined it all: hung on state, these animations would play by themselves on first render — before anyone saw the page, the icon had already spun once.

The fix is a latch: the theme-switched class is added only after the user’s first real tap. Animation exists for interaction, not for rendering.

Degradation is part of dignity

Users with prefers-reduced-motion get a clean instant switch; unsupported browsers skip the page cross-fade while the icon animation stays. Every user gets the complete feature — only the tempo differs.

Motion is a gift for those willing to watch, not a gate for everyone.

Comments

← Digital Garden