NelsonLabs
CSS Styling/Transitions & Animations

Transitions & Animations

Animations and transitions are the difference between a UI that feels alive and one that feels static. The key is restraint โ€” animation should guide attention, not distract from content.

Transitions โ€” smooth state changes

CSS transitions
css
/* transition: property duration timing-function delay */

button {
  background: #C96A30;
  transform: scale(1);
  transition: background 0.2s ease, transform 0.15s ease;
}

button:hover {
  background: #DC7C40;
  transform: scale(1.03);
}

/* Transition all changing properties */
.card {
  transition: all 0.2s ease;
}

/* Common timing functions */
transition-timing-function: ease;         /* slow-fast-slow (default) */
transition-timing-function: linear;       /* constant speed */
transition-timing-function: ease-in;      /* starts slow */
transition-timing-function: ease-out;     /* ends slow */
transition-timing-function: ease-in-out;  /* slow start and end */
transition-timing-function: cubic-bezier(0.25, 0.46, 0.45, 0.94); /* custom */

Keyframe animations

@keyframes animations
css
/* Define the animation */
@keyframes fadeIn {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: translateY(0); }
}

@keyframes pulse {
  0%, 100% { opacity: 1; }
  50%       { opacity: 0.5; }
}

@keyframes spin {
  from { transform: rotate(0deg); }
  to   { transform: rotate(360deg); }
}

/* Apply the animation */
.hero-text {
  animation: fadeIn 0.6s ease forwards;
}

.loading-dot {
  animation: pulse 1.5s ease infinite;
}

.spinner {
  animation: spin 1s linear infinite;
}

/* animation shorthand: name duration timing fill-mode */
animation: fadeIn 0.5s ease forwards;

TIP

Respect reduced motion. Some users experience motion sickness or have vestibular disorders. Always wrap heavy animations in a prefers-reduced-motion media query. Remove or reduce animations for users who opt out.

Accessible animations
css
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }
}