HC

Animations & Transitions

HTML & CSS · 8 entries

Transitions

syntax
transition: property duration timing-function delay;
transition: all 0.3s ease;
example
.button {
  background: #2563eb;
  transition: background-color 0.2s ease, transform 0.2s ease;
}

.button:hover {
  background: #1d4ed8;
  transform: translateY(-1px);
}

/* Transition specific properties for performance */
.card {
  transition: box-shadow 0.2s ease, transform 0.3s ease;
}

Note Prefer transitioning specific properties rather than using 'all' since transitioning everything can cause unexpected side effects and reduced performance. Stick to transform and opacity for the smoothest animations (they are GPU-accelerated).

Keyframe Animations

syntax
@keyframes name {
  from { ... }
  to { ... }
}

@keyframes name {
  0% { ... }
  50% { ... }
  100% { ... }
}
example
@keyframes fadeSlideIn {
  from {
    opacity: 0;
    transform: translateY(20px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.card {
  animation: fadeSlideIn 0.4s ease-out;
}

Note Keyframe animations run independently from state changes unlike transitions which need a trigger. Define keyframes globally and apply them with the animation property. The animation runs once by default.

Animation Property

syntax
animation: name duration timing-function delay iteration-count direction fill-mode;
example
.spinner {
  animation: spin 1s linear infinite;
}

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

.pulse {
  animation: pulse 2s ease-in-out infinite alternate;
}

@keyframes pulse {
  from { transform: scale(1); }
  to { transform: scale(1.05); }
}

Note Key values: infinite loops forever. alternate reverses direction each cycle. forwards (fill-mode) keeps the final keyframe state after the animation ends. Combine multiple animations with commas.

Transform

syntax
transform: translate() | rotate() | scale() | skew();
translate: x y;
rotate: angle;
scale: value;
example
.card:hover {
  transform: translateY(-4px) scale(1.02);
}

.rotated {
  rotate: 12deg;
}

.shifted {
  translate: 10px -5px;
}

.mirror {
  scale: -1 1; /* flip horizontally */
}

Note Modern CSS supports individual transform properties (translate, rotate, scale) that can be animated independently. The older transform property applies all transforms at once. Transforms do not affect document flow and are GPU-accelerated.

Timing Functions

syntax
transition-timing-function: ease | linear | ease-in | ease-out | ease-in-out | cubic-bezier(x1, y1, x2, y2);
example
.slide-in {
  transition: transform 0.3s ease-out;
}

.bounce {
  transition: transform 0.5s cubic-bezier(0.34, 1.56, 0.64, 1);
}

.smooth {
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}

Note ease-out starts fast and slows down, ideal for enter animations. ease-in starts slow and speeds up, better for exit animations. Custom cubic-bezier values give you fine control. Values beyond 0-1 on the y-axis create overshoot/bounce effects.

View Transitions

syntax
/* Opt elements into the transition */
.element {
  view-transition-name: unique-name;
}

/* Customize the transition */
::view-transition-old(name) { ... }
::view-transition-new(name) { ... }
example
.page-header {
  view-transition-name: header;
}

.product-image {
  view-transition-name: product-hero;
}

::view-transition-old(product-hero) {
  animation: fadeOut 0.2s ease-out;
}

::view-transition-new(product-hero) {
  animation: fadeIn 0.3s ease-in;
}

/* Trigger in JS: document.startViewTransition(() => updateDOM()) */

Note View transitions animate between DOM states with a cross-fade by default. Assign view-transition-name to elements that should animate individually rather than cross-fading with the whole page. Each name must be unique on the page. Triggered via JavaScript's document.startViewTransition() API.

Smooth Scrolling

syntax
scroll-behavior: smooth | auto;
example
html {
  scroll-behavior: smooth;
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
}

Note Applies to scrolling triggered by anchor links and JavaScript scrollTo/scrollIntoView calls. Always disable smooth scrolling for users who prefer reduced motion. This does not affect user-initiated scroll (mouse wheel, trackpad).

Will-Change & Performance

syntax
will-change: property;
/* Remove after animation completes */
example
.animated-card {
  will-change: transform;
  transition: transform 0.3s ease;
}

/* Apply will-change only when needed */
.card-container:hover .animated-card {
  will-change: transform;
}

.animated-card:hover {
  transform: scale(1.05);
}

Note will-change hints to the browser to prepare for an animation, promoting the element to its own compositor layer. Overusing it wastes memory. Apply it only to elements that will actually animate and remove it after the animation finishes if possible.