CSS Cheatsheet

Transitions and Animations

Use this CSS reference while you build software engineering projects, review code for technical interview prep, or polish examples for a software engineer resume.

transition Shorthand

/* property duration timing-function delay */
transition: color 0.2s ease;
transition: all 0.3s ease-in-out;
transition: opacity 0.3s ease, transform 0.4s ease-out;
transition: none;

Transition Longhand Properties

transition-property: color;           /* which property to animate */
transition-property: all;             /* all animatable properties */
transition-property: opacity, transform;
transition-property: none;

transition-duration: 0.3s;
transition-duration: 300ms;
transition-duration: 0.3s, 0.5s;     /* per-property durations */

transition-timing-function: ease;
transition-timing-function: linear;
transition-timing-function: ease-in;
transition-timing-function: ease-out;
transition-timing-function: ease-in-out;
transition-timing-function: step-start;
transition-timing-function: step-end;
transition-timing-function: steps(4, end);
transition-timing-function: cubic-bezier(0.68, -0.55, 0.265, 1.55); /* bounce */

transition-delay: 0s;
transition-delay: 100ms;
transition-delay: -0.1s;   /* negative: start partway through */

Easing Functions

ValueDescription
linearConstant speed
easeSlow start, fast middle, slow end (default)
ease-inSlow start
ease-outSlow end
ease-in-outSlow start and end
step-startJump at start (steps(1, start))
step-endJump at end (steps(1, end))
steps(n, start|end)n equal steps
cubic-bezier(x1,y1,x2,y2)Custom Bezier curve
linear(...)Multi-stop linear
/* CSS Easing Functions Level 2 — linear() with multiple stops */
transition-timing-function: linear(0, 0.25 25%, 0.5 50%, 0.75 75%, 1);
/* Spring-like bounce */
transition-timing-function: linear(
  0, 0.004, 0.016, 0.035, 0.063 9.09%, 0.141,
  0.25, 0.391, 0.562, 0.765, 1, 1.208, 1.407,
  1.562, 1.492, 1.373, 1.265, 1.182, 1.108 63.64%,
  1.062, 1.022, 0.991, 0.966, 0.949, 0.938 84.09%,
  0.934, 0.938, 0.951, 0.968, 0.984, 0.997, 1.007, 1
);

@keyframes

@keyframes slidein {
  from { transform: translateX(-100%); }
  to   { transform: translateX(0); }
}

@keyframes pulse {
  0%   { transform: scale(1); }
  50%  { transform: scale(1.1); }
  100% { transform: scale(1); }
}

@keyframes fade-in-up {
  from {
    opacity: 0;
    transform: translateY(1rem);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* Can omit from/to and use 0%/100% */
/* Multiple properties at same keyframe are fine */

animation Shorthand

/* name duration timing-function delay iteration-count direction fill-mode play-state */
animation: slidein 0.4s ease-out 0s 1 normal forwards running;

/* Common patterns */
animation: pulse 2s ease-in-out infinite;
animation: fade-in-up 0.5s ease both;
animation: none;

/* Multiple animations */
animation:
  slide 0.4s ease,
  fade 0.6s ease 0.2s;

Animation Longhand Properties

animation-name: slidein;
animation-name: slidein, pulse;   /* multiple */
animation-name: none;

animation-duration: 0.4s;
animation-duration: 400ms;

animation-timing-function: ease;  /* same values as transition-timing-function */

animation-delay: 0.1s;
animation-delay: -0.5s;           /* negative: start mid-animation */

animation-iteration-count: 1;
animation-iteration-count: infinite;
animation-iteration-count: 2.5;   /* partial iterations */

animation-direction: normal;       /* plays forward */
animation-direction: reverse;      /* plays backward */
animation-direction: alternate;    /* forward, then backward, then forward… */
animation-direction: alternate-reverse;

animation-fill-mode: none;         /* default — no styles outside animation */
animation-fill-mode: forwards;     /* keeps last-keyframe styles after */
animation-fill-mode: backwards;    /* applies first-keyframe styles during delay */
animation-fill-mode: both;         /* both forwards and backwards */

animation-play-state: running;
animation-play-state: paused;      /* pause/resume via JS or :hover */

animation-composition: replace;    /* default */
animation-composition: add;        /* add to underlying value */
animation-composition: accumulate; /* accumulate (good for transforms) */

animation-timeline and Scroll-Driven Animations

/* Scroll-driven animation (no JavaScript needed) */
@keyframes reveal {
  from { opacity: 0; transform: translateY(2rem); }
  to   { opacity: 1; transform: translateY(0); }
}

.card {
  animation: reveal linear both;
  animation-timeline: scroll(root);   /* drives off root scroll */
  animation-range: entry 0% entry 30%;
}

/* Named scroll timelines */
.scroll-container {
  overflow-y: scroll;
  scroll-timeline: --my-scroll block;
}
.animated-item {
  animation: slide linear;
  animation-timeline: --my-scroll;
}

/* View timeline (element entering/leaving viewport) */
.section {
  animation: fade-in both linear;
  animation-timeline: view();
  animation-range: entry 0% entry 40%;
}

transition-behavior (Discrete Transitions)

/* Allows transitioning properties that aren't interpolatable (e.g., display) */
.panel {
  transition: opacity 0.3s, display 0.3s;
  transition-behavior: allow-discrete;
  /* or shorthand */
  transition: opacity 0.3s, display 0.3s allow-discrete;
}

/* Starting style for discrete transitions */
@starting-style {
  .panel { opacity: 0; }
}

Animatable Properties

Most numeric/length/color properties are animatable. Non-animatable properties change instantly.

Commonly animated: opacity, transform, color, background-color, border-color, width, height, margin, padding, top, left, font-size, letter-spacing, box-shadow, filter, clip-path, border-radius.

Not animatable (discrete): display, visibility, position, overflow, content.

For best performance, stick to animating opacity and transform — they are compositor-accelerated and don't trigger layout or paint.

prefers-reduced-motion

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

Common Animation Patterns

Fade In

@keyframes fade-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}
.fade-in { animation: fade-in 0.3s ease both; }

Slide in from Left

@keyframes slide-left {
  from { transform: translateX(-100%); }
  to   { transform: translateX(0); }
}

Spin (loading)

@keyframes spin {
  to { transform: rotate(360deg); }
}
.spinner { animation: spin 1s linear infinite; }

Shake

@keyframes shake {
  0%, 100% { transform: translateX(0); }
  20%, 60%  { transform: translateX(-6px); }
  40%, 80%  { transform: translateX(6px); }
}
.shake { animation: shake 0.5s ease; }

Heartbeat Pulse

@keyframes heartbeat {
  0%, 100% { transform: scale(1); }
  14%       { transform: scale(1.3); }
  28%       { transform: scale(1); }
  42%       { transform: scale(1.3); }
  70%       { transform: scale(1); }
}

Pause on Hover

.card { animation: slide 4s linear infinite; }
.card:hover { animation-play-state: paused; }

JavaScript and Animation Events

/* Trigger animations via class change */
.hidden { opacity: 0; }
.visible { animation: fade-in 0.3s ease both; }
/* Events: animationstart, animationend, animationiteration */
/* Events: transitionstart, transitionend, transitioncancel, transitionrun */