Mastering CSS: Animations, Transitions, and Responsive Design (Part 3)

This article walks through CSS transition syntax and parameters, demonstrates common transition effects, explains 2D and 3D transforms, details @keyframes animation properties and fill‑modes, introduces CSS custom properties for theming, shows media‑query‑based responsive design techniques, and covers performance tips such as will‑change and scroll‑snap.

CodeNotes
CodeNotes
CodeNotes
Mastering CSS: Animations, Transitions, and Responsive Design (Part 3)

1. transition animation

The transition property creates a smooth animation when a CSS property value changes and is the simplest and most common animation method.

1.1 Basic syntax

/* syntax: property duration timing-function delay */
.btn {
  background: #0052d9;
  transition: background 0.3s ease;
}

.btn:hover {
  background: #003db3;
}

1.2 Parameter details

.element {
  /* properties to transition */
  transition-property: background, transform, opacity;
  /* all properties (use with caution, performance impact) */
  transition-property: all;

  /* duration */
  transition-duration: 0.3s;
  transition-duration: 300ms;

  /* timing functions */
  transition-timing-function: ease;        /* default: fast then slow */
  transition-timing-function: linear;      /* constant speed */
  transition-timing-function: ease-in;     /* slow to fast */
  transition-timing-function: ease-out;    /* fast to slow */
  transition-timing-function: ease-in-out;/* slow‑fast‑slow */
  transition-timing-function: cubic-bezier(0.34, 1.56, 0.64, 1); /* bounce */
  transition-timing-function: steps(4, end); /* step animation */

  /* delay */
  transition-delay: 0.1s;
}

/* shorthand (multiple properties separated by commas) */
.card {
  transition:
    transform 0.3s ease,
    box-shadow 0.3s ease,
    opacity 0.2s ease 0.1s; /* opacity delayed */
}

1.3 Common transition effects

/* button hover feedback */
.btn {
  background: #0052d9;
  color: #fff;
  border: none;
  padding: 10px 20px;
  border-radius: 6px;
  cursor: pointer;
  transition: background 0.2s, transform 0.15s, box-shadow 0.2s;
}

.btn:hover {
  background: #003db3;
  box-shadow: 0 4px 12px rgba(0, 82, 217, 0.4);
}

.btn:active { transform: scale(0.97); }

/* card hover lift */
.card {
  transition: transform 0.3s ease, box-shadow 0.3s ease;
  border-radius: 12px;
  box-shadow: 0 2px 8px rgba(0,0,0,0.08);
}

.card:hover {
  transform: translateY(-6px);
  box-shadow: 0 12px 32px rgba(0,0,0,0.16);
}

/* link underline expansion */
.fancy-link {
  text-decoration: none;
  color: #0052d9;
  position: relative;
}
.fancy-link::after {
  content: '';
  position: absolute;
  bottom: -2px;
  left: 0;
  width: 0;
  height: 2px;
  background: currentColor;
  transition: width 0.3s ease;
}
.fancy-link:hover::after { width: 100%; }

/* navigation menu expand */
.dropdown { max-height: 0; overflow: hidden; transition: max-height 0.4s ease; }
.dropdown.open { max-height: 500px; }

2. transform

The transform property can translate, rotate, scale, or skew elements without affecting document flow, offering excellent performance.

2.1 2D transforms

.element {
  /* translate */
  transform: translateX(20px);
  transform: translateY(-50%);
  transform: translate(20px, -10px);

  /* scale */
  transform: scaleX(1.2);
  transform: scaleY(0.8);
  transform: scale(1.2);          /* uniform */
  transform: scale(1.2, 0.8);    /* non‑uniform */

  /* rotate */
  transform: rotate(45deg);
  transform: rotate(-90deg);

  /* skew */
  transform: skewX(10deg);
  transform: skewY(5deg);
  transform: skew(10deg, 5deg);

  /* multiple transforms (order matters) */
  transform: translateX(50px) rotate(45deg) scale(1.2);
}

2.2 3D transforms

.card-3d {
  transform-style: preserve-3d; /* children also in 3D space */
  perspective: 1000px;          /* perspective distance */
}

/* flip card effect */
.flip-card {
  perspective: 1000px;
  width: 200px;
  height: 280px;
}
.flip-card__inner {
  position: relative;
  width: 100%;
  height: 100%;
  transform-style: preserve-3d;
  transition: transform 0.6s cubic-bezier(0.4, 0, 0.2, 1);
}
.flip-card:hover .flip-card__inner { transform: rotateY(180deg); }
.flip-card__front,
.flip-card__back {
  position: absolute;
  inset: 0;
  backface-visibility: hidden;
  border-radius: 12px;
}
.flip-card__back {
  transform: rotateY(180deg);
  background: #0052d9;
  color: #fff;
}

2.3 transform-origin

.element {
  transform-origin: center;        /* default */
  transform-origin: top left;    /* top‑left corner */
  transform-origin: 0 0;         /* same as left top */
  transform-origin: 50% 100%;   /* bottom center */
}

/* left‑side expanding menu */
.menu-item::before {
  transform-origin: left;
  transform: scaleX(0);
  transition: transform 0.3s ease;
}
.menu-item:hover::before { transform: scaleX(1); }

3. @keyframes animation

transition

only triggers on state changes, while animation can play complex multi‑stage animations automatically.

3.1 Basic usage

/* define keyframes */
@keyframes fadeIn {
  from { opacity: 0; transform: translateY(20px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* percentage syntax */
@keyframes bounce {
  0%   { transform: translateY(0); }
  30%  { transform: translateY(-30px); }
  50%  { transform: translateY(-20px); }
  70%  { transform: translateY(-10px); }
  100% { transform: translateY(0); }
}

/* apply animation */
.element { animation: fadeIn 0.5s ease forwards; }

3.2 animation property details

.element {
  animation-name: fadeIn;
  animation-duration: 0.5s;
  animation-timing-function: ease;
  animation-delay: 0.2s;
  animation-iteration-count: 1;   /* use infinite for endless */
  animation-direction: normal;    /* normal | reverse | alternate */
  animation-fill-mode: forwards;  /* keep final state */
  animation-play-state: running;

  /* shorthand */
  animation: fadeIn 0.5s ease 0.2s 1 normal forwards;

  /* multiple animations */
  animation:
    fadeIn 0.5s ease forwards,
    slideUp 0.4s ease 0.1s forwards;
}

3.3 fill‑mode explanation

/* none (default): revert to initial state after animation */
/* forwards: retain the last keyframe */
/* backwards: apply first keyframe during delay */
/* both: combine forwards and backwards */
.fade-in { animation: fadeIn 0.5s ease forwards; }

3.4 Practical animation snippets

/* loading spinner */
@keyframes spin { to { transform: rotate(360deg); } }
.spinner {
  width: 24px;
  height: 24px;
  border: 3px solid #e0e0e0;
  border-top-color: #0052d9;
  border-radius: 50%;
  animation: spin 0.8s linear infinite;
}

/* pulse (heartbeat) */
@keyframes pulse {
  0%, 100% { transform: scale(1); opacity: 1; }
  50%       { transform: scale(1.05); opacity: 0.8; }
}
.live-badge { animation: pulse 1.5s ease-in-out infinite; }

/* skeleton shimmer */
@keyframes shimmer { 0% { background-position: -200% 0; } 100% { background-position: 200% 0; } }
.skeleton {
  background: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
  background-size: 200% 100%;
  animation: shimmer 1.5s infinite;
  border-radius: 4px;
}

/* shake for error feedback */
@keyframes shake {
  0%, 100% { transform: translateX(0); }
  10%, 50%, 90% { transform: translateX(-8px); }
  30%, 70% { transform: translateX(8px); }
}
.input-error { animation: shake 0.5s ease; }

/* staggered page entry */
@keyframes slideUp {
  from { opacity: 0; transform: translateY(30px); }
  to   { opacity: 1; transform: translateY(0); }
}
.list-item:nth-child(1) { animation: slideUp 0.4s ease 0s forwards; }
.list-item:nth-child(2) { animation: slideUp 0.4s ease 0.1s forwards; }
.list-item:nth-child(3) { animation: slideUp 0.4s ease 0.2s forwards; }
.list-item:nth-child(4) { animation: slideUp 0.4s ease 0.3s forwards; }
/* more elegant: use CSS variable */
.list-item { opacity: 0; animation: slideUp 0.4s ease calc(var(--index) * 0.1s) forwards; }

3.5 CSS custom properties with animation

<ul>
  <li style="--index: 0">First item</li>
  <li style="--index: 1">Second item</li>
  <li style="--index: 2">Third item</li>
</ul>
li { opacity: 0; animation: slideUp 0.4s ease calc(var(--index, 0) * 0.1s) forwards; }

4. CSS custom properties (variables)

CSS variables are a core modern feature that greatly improve maintainability.

4.1 Basic usage

/* define variables on :root (global) */
:root {
  --color-primary: #0052d9;
  --color-success: #52c41a;
  --color-danger:  #ff4d4f;
  --color-warning: #faad14;
  --color-text:    #333;
  --color-text-secondary: #999;
  --color-bg:      #f0f2f5;

  --spacing-xs: 4px;
  --spacing-sm: 8px;
  --spacing-md: 16px;
  --spacing-lg: 24px;
  --spacing-xl: 32px;

  --border-radius: 8px;
  --border-radius-sm: 4px;
  --border-radius-lg: 16px;
  --border-radius-circle: 50%;

  --shadow-sm: 0 1px 4px rgba(0,0,0,0.06);
  --shadow-md: 0 4px 16px rgba(0,0,0,0.08);
  --shadow-lg: 0 8px 32px rgba(0,0,0,0.16);
}

.btn-primary { background: var(--color-primary); border-radius: var(--border-radius); padding: var(--spacing-sm) var(--spacing-md); }
.element { color: var(--custom-color, #333); }

4.2 Dark‑mode switch

:root {
  --color-bg: #ffffff;
  --color-text: #333333;
  --color-border: #e8e8e8;
  --color-surface: #f5f5f5;
}

[data-theme="dark"],
@media (prefers-color-scheme: dark) {
  :root {
    --color-bg: #1a1a1a;
    --color-text: #e0e0e0;
    --color-border: #333333;
    --color-surface: #2a2a2a;
  }
}

body { background: var(--color-bg); color: var(--color-text); transition: background 0.3s, color 0.3s; }
.card { background: var(--color-surface); border: 1px solid var(--color-border); }

5. Responsive design

5.1 Media query basics

@media (condition) { /* styles */ }
/* breakpoints – mobile‑first (recommended) */
@media (min-width: 576px) { /* small phones landscape, large phones */ }
@media (min-width: 768px) { /* tablets */ }
@media (min-width: 992px) { /* small desktops */ }
@media (min-width: 1200px) { /* large desktops */ }
/* desktop‑first (traditional) */
@media (max-width: 1199px) { }
@media (max-width: 991px)  { }
@media (max-width: 767px)  { }

5.2 Feature detection in media queries

/* orientation */
@media (orientation: landscape) { }
@media (orientation: portrait)  { }
/* hover capability */
@media (hover: hover) { .btn:hover { background: #003db3; } }
/* prefers‑color‑scheme */
@media (prefers-color-scheme: dark) { :root { --color-bg: #1a1a1a; } }
/* prefers‑reduced‑motion */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; }
}
/* print */
@media print { .sidebar, .header, .ads { display: none; } body { font-size: 12pt; } }
/* combined conditions */
@media (min-width: 768px) and (max-width: 1199px) { /* tablets only */ }
@media (max-width: 768px), (orientation: portrait) { /* mobile or portrait */ }

5.3 Mobile‑first strategy

/* default (mobile) */
.container { padding: 0 16px; }
.hero-title { font-size: 28px; line-height: 1.3; }
.card-grid { display: grid; grid-template-columns: 1fr; gap: 16px; }
/* tablet */
@media (min-width: 768px) {
  .container { padding: 0 24px; }
  .hero-title { font-size: 40px; }
  .card-grid { grid-template-columns: repeat(2, 1fr); }
}
/* desktop */
@media (min-width: 1200px) {
  .container { max-width: 1160px; margin: 0 auto; padding: 0 40px; }
  .hero-title { font-size: 56px; }
  .card-grid { grid-template-columns: repeat(3, 1fr); gap: 24px; }
}

5.4 Responsive typography with clamp()

The clamp(min, preferred, max) function provides an elegant solution for fluid fonts.

.hero-title { font-size: clamp(24px, 4vw + 10px, 56px); }
.container { padding: 0 clamp(16px, 5vw, 80px); }

5.5 Responsive images

img { max-width: 100%; height: auto; }
.cover { width: 100%; aspect-ratio: 16 / 9; object-fit: cover; }
.avatar { width: 40px; height: 40px; border-radius: 50%; object-fit: cover; }

6. Progress‑bar animation with CSS variables

<div class="progress-bar">
  <div class="progress-bar__fill" style="--progress: 75%"></div>
</div>
@keyframes progressFill { from { width: 0; } to { width: var(--progress); } }
.progress-bar {
  height: 8px;
  background: #e8e8e8;
  border-radius: 100px;
  overflow: hidden;
}
.progress-bar__fill {
  height: 100%;
  width: var(--progress);
  background: linear-gradient(90deg, #0052d9, #36a9e1);
  border-radius: 100px;
  animation: progressFill 1s cubic-bezier(0.4, 0, 0.2, 1) forwards;
}

7. will-change and performance optimization

.animated-element { will-change: transform, opacity; }
.animated-element.animation-done { will-change: auto; }
/* Recommendation: apply only to frequently animated elements; avoid overuse to prevent excessive GPU memory consumption */

GPU acceleration principle : Prefer transform and opacity for animations; avoid properties that trigger layout such as width, height, margin, top, etc.

Layout (reflow) : width, height, margin – poor performance.

Paint : background, color – average performance.

Composite : transform, opacity – good performance.

8. Practical: page‑loading skeleton

<div class="page-skeleton">
  <div class="skeleton skeleton--title"></div>
  <div class="skeleton skeleton--text"></div>
  <div class="skeleton skeleton--text skeleton--short"></div>
  <div class="skeleton-cards">
    <div class="skeleton skeleton--card"></div>
    <div class="skeleton skeleton--card"></div>
    <div class="skeleton skeleton--card"></div>
  </div>
</div>
@keyframes shimmer {
  0%   { background-position: -400px 0; }
  100% { background-position: 400px 0; }
}
.skeleton {
  background: linear-gradient(90deg, #f2f2f2 25%, #eaeaea 50%, #f2f2f2 75%);
  background-size: 800px 100%;
  animation: shimmer 1.5s infinite linear;
  border-radius: 4px;
}
.skeleton--title { height: 28px; width: 60%; margin-bottom: 16px; }
.skeleton--text { height: 16px; margin-bottom: 8px; }
.skeleton--short { width: 70%; }
.skeleton-cards { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; margin-top: 24px; }
.skeleton--card { height: 200px; border-radius: 8px; }

9. Scroll‑related features

Smooth scrolling

html { scroll-behavior: smooth; }
/* smooth scroll for anchor links */

scroll‑snap (scroll anchoring)

/* horizontal carousel */
.carousel {
  display: flex;
  overflow-x: auto;
  scroll-snap-type: x mandatory; /* or proximity */
  gap: 16px;
  -ms-overflow-style: none;
  scrollbar-width: none;
}
.carousel::-webkit-scrollbar { display: none; }
.carousel__item { flex: 0 0 300px; scroll-snap-align: start; }

/* full‑page paging */
.fullpage { height: 100vh; overflow-y: scroll; scroll-snap-type: y mandatory; }
.fullpage__section { height: 100vh; scroll-snap-align: start; }

Conclusion

transition : state‑change animation; prefer transform / opacity for performance.

transform : translate/rotate/scale/skew without affecting layout.

animation : automatic multi‑stage animation.

CSS variables : foundation for theming and dynamic styles.

media queries : mobile‑first, min‑width progressive enhancement.

clamp() : elegant solution for fluid typography and spacing.

performance : prioritize transform / opacity; use will-change sparingly.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

cssresponsive designcss-variablestransformmedia queriesanimationstransitions
CodeNotes
Written by

CodeNotes

Discuss code and AI, and document daily life and personal growth.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.