Snap the theme, don't fade it

Turn transitions off for one frame while the theme flips.

Paco Courseypaco.me
It's difficult to transition between themes smoothly. Adding a CSS transition to every element negatively impacts rendering performance, and it also won't work for images, icons, and CSS properties that don't support transitions.
Disable transitions on theme toggle · Mar 2020Read article ↗

Flip the theme

Toggle each app and watch the colors change.

Transitions left onBad
Inbox
Weekly digest12 new replies
Design review2m
Invoice 04121h
theme = next
Frozen for one frameGood
Inbox
Weekly digest12 new replies
Design review2m
Invoice 04121h
transition: none !important
function setTheme(next) {
  const style = document.createElement("style");
  style.textContent = "*, *::before, *::after { transition: none !important }";
  document.head.append(style);

  document.documentElement.dataset.theme = next;

  getComputedStyle(document.body).opacity;   // force a reflow
  requestAnimationFrame(() => style.remove());
}

Why it matters, pros and cons

Why it matters

Color fades run per element at different speeds, and icons and images can't fade. The result is a messy wash.

Pros

  • Every element changes in the same frame, so the switch looks like one clean cut.
  • Hover and press transitions come back one frame later, untouched.
  • One small helper covers the whole page and costs no per-element work.

Cons

  • Needs a reflow before the frame is restored, or the fades still run.
  • A strict CSP blocks the injected style tag unless it carries a nonce.
  • Some teams want the soft fade; this removes it everywhere.