CSS Animations & Transitions: دليل شامل للحركات والانتقالات في الويب

CSS

CSS Animations & Transitions: دليل شامل للحركات والانتقالات في الويب
إتقان CSS Animations و Transitions - keyframes، transforms، timing functions، وتأثيرات الحركة المتقدمة لتجارب ويب جذابة.
#CSS#Animations#Transitions#Keyframes#Transform#Motion#Effects

CSS Animations & Transitions: دليل شامل للحركات والانتقالات في الويب

الدليل الاحترافي من إعداد علاء عامر - خبير تطوير الويب والتصميم

CSS Animations تضفي الحياة على واجهات الويب. تعلم كيفية إنشاء تأثيرات حركية سلسة وجذابة تحسن تجربة المستخدم.


1️⃣ CSS Transitions Basics

Understanding Transitions

/* Basic transition syntax */
.transition-example {
  /* Properties to animate */
  background-color: #3498db;
  transform: scale(1);
  opacity: 1;

  /* Transition configuration */
  transition-property: all; /* which properties to animate */
  transition-duration: 0.3s; /* animation duration */
  transition-timing-function: ease; /* animation curve */
  transition-delay: 0s; /* delay before starting */

  /* Shorthand syntax */
  transition: all 0.3s ease 0s;
}

.transition-example:hover {
  background-color: #e74c3c;
  transform: scale(1.1);
  opacity: 0.8;
}

/* Multiple property transitions */
.multi-transition {
  background: #2ecc71;
  border-radius: 4px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);

  /* Different transitions for different properties */
  transition:
    background-color 0.3s ease,
    transform 0.5s cubic-bezier(0.68, -0.55, 0.265, 1.55),
    box-shadow 0.2s ease-out;
}

.multi-transition:hover {
  background: #27ae60;
  transform: translateY(-5px) rotate(2deg);
  box-shadow: 0 8px 25px rgba(0, 0, 0, 0.2);
}

2️⃣ Timing Functions and Easing

/* Built-in timing functions */
.timing-examples {
  transition-duration: 0.5s;
}

.linear {
  transition-timing-function: linear;
}
.ease {
  transition-timing-function: ease;
}
.ease-in {
  transition-timing-function: ease-in;
}
.ease-out {
  transition-timing-function: ease-out;
}
.ease-in-out {
  transition-timing-function: ease-in-out;
}

/* Custom cubic-bezier curves */
.custom-ease-1 {
  transition-timing-function: cubic-bezier(0.25, 0.46, 0.45, 0.94);
}
.custom-ease-2 {
  transition-timing-function: cubic-bezier(
    0.68,
    -0.55,
    0.265,
    1.55
  ); /* bouncy */
}
.custom-ease-3 {
  transition-timing-function: cubic-bezier(
    0.95,
    0.05,
    0.795,
    0.035
  ); /* dramatic */
}

/* Steps timing function */
.steps-animation {
  transition: transform 1s steps(4, end);
}

.steps-animation:hover {
  transform: translateX(200px);
  /* Animation will happen in 4 discrete steps */
}

/* Practical button transitions */
.button {
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  color: white;
  border: none;
  padding: 12px 24px;
  border-radius: 6px;
  cursor: pointer;
  position: relative;
  overflow: hidden;

  transition: all 0.3s cubic-bezier(0.23, 1, 0.32, 1);
}

.button::before {
  content: "";
  position: absolute;
  top: 0;
  left: -100%;
  width: 100%;
  height: 100%;
  background: linear-gradient(
    90deg,
    transparent,
    rgba(255, 255, 255, 0.2),
    transparent
  );
  transition: left 0.5s ease;
}

.button:hover {
  transform: translateY(-2px);
  box-shadow: 0 7px 14px rgba(102, 126, 234, 0.4);
}

.button:hover::before {
  left: 100%;
}

.button:active {
  transform: translateY(0);
  transition-duration: 0.1s;
}

3️⃣ CSS Keyframe Animations

/* Basic keyframe syntax */
@keyframes slideInFromLeft {
  0% {
    transform: translateX(-100%);
    opacity: 0;
  }
  100% {
    transform: translateX(0);
    opacity: 1;
  }
}

/* Using the animation */
.slide-in {
  animation-name: slideInFromLeft;
  animation-duration: 0.8s;
  animation-timing-function: ease-out;
  animation-delay: 0s;
  animation-iteration-count: 1;
  animation-direction: normal;
  animation-fill-mode: both;
  animation-play-state: running;

  /* Shorthand syntax */
  /* animation: slideInFromLeft 0.8s ease-out both; */
}

/* Complex multi-step animation */
@keyframes complexMove {
  0% {
    transform: translateX(0) rotate(0deg);
    background: #3498db;
    border-radius: 4px;
  }
  25% {
    transform: translateX(100px) rotate(90deg);
    background: #e74c3c;
    border-radius: 50%;
  }
  50% {
    transform: translateX(100px) translateY(-50px) rotate(180deg);
    background: #2ecc71;
    border-radius: 4px;
  }
  75% {
    transform: translateX(0) translateY(-50px) rotate(270deg);
    background: #f39c12;
    border-radius: 50%;
  }
  100% {
    transform: translateX(0) translateY(0) rotate(360deg);
    background: #9b59b6;
    border-radius: 4px;
  }
}

.complex-animation {
  width: 50px;
  height: 50px;
  animation: complexMove 3s ease-in-out infinite;
}

/* Practical animations library */

/* Fade animations */
@keyframes fadeIn {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

@keyframes fadeInUp {
  from {
    opacity: 0;
    transform: translateY(30px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

@keyframes fadeInDown {
  from {
    opacity: 0;
    transform: translateY(-30px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* Scale animations */
@keyframes zoomIn {
  from {
    opacity: 0;
    transform: scale(0.3);
  }
  to {
    opacity: 1;
    transform: scale(1);
  }
}

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

/* Bounce animation */
@keyframes bounce {
  0%,
  20%,
  53%,
  80%,
  100% {
    animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
    transform: translate3d(0, 0, 0);
  }
  40%,
  43% {
    animation-timing-function: cubic-bezier(0.755, 0.05, 0.855, 0.06);
    transform: translate3d(0, -30px, 0);
  }
  70% {
    animation-timing-function: cubic-bezier(0.755, 0.05, 0.855, 0.06);
    transform: translate3d(0, -15px, 0);
  }
  90% {
    transform: translate3d(0, -4px, 0);
  }
}

/* Shake animation */
@keyframes shake {
  0%,
  100% {
    transform: translateX(0);
  }
  10%,
  30%,
  50%,
  70%,
  90% {
    transform: translateX(-10px);
  }
  20%,
  40%,
  60%,
  80% {
    transform: translateX(10px);
  }
}

/* Rotation animations */
@keyframes rotate {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
}

@keyframes flip {
  from {
    transform: perspective(400px) rotateY(0);
  }
  to {
    transform: perspective(400px) rotateY(180deg);
  }
}

4️⃣ Advanced Animation Effects

/* Loading animations */
@keyframes spinner {
  0% {
    transform: rotate(0deg);
  }
  100% {
    transform: rotate(360deg);
  }
}

.loading-spinner {
  width: 40px;
  height: 40px;
  border: 4px solid #f3f3f3;
  border-top: 4px solid #3498db;
  border-radius: 50%;
  animation: spinner 1s linear infinite;
}

/* Dots loading animation */
@keyframes dotsBounce {
  0%,
  80%,
  100% {
    transform: scale(0);
  }
  40% {
    transform: scale(1);
  }
}

.loading-dots {
  display: inline-block;
  position: relative;
  width: 80px;
  height: 80px;
}

.loading-dots div {
  position: absolute;
  top: 33px;
  width: 13px;
  height: 13px;
  border-radius: 50%;
  background: #3498db;
  animation: dotsBounce 1.4s infinite ease-in-out both;
}

.loading-dots div:nth-child(1) {
  left: 8px;
  animation-delay: -0.32s;
}
.loading-dots div:nth-child(2) {
  left: 32px;
  animation-delay: -0.16s;
}
.loading-dots div:nth-child(3) {
  left: 56px;
  animation-delay: 0s;
}

/* Typing animation */
@keyframes typing {
  from {
    width: 0;
  }
  to {
    width: 100%;
  }
}

@keyframes blinkCaret {
  from,
  to {
    border-color: transparent;
  }
  50% {
    border-color: #333;
  }
}

.typewriter {
  overflow: hidden;
  border-right: 2px solid #333;
  white-space: nowrap;
  margin: 0 auto;
  animation:
    typing 3.5s steps(40, end),
    blinkCaret 0.75s step-end infinite;
}

/* Floating animation */
@keyframes float {
  0% {
    transform: translateY(0px);
  }
  50% {
    transform: translateY(-20px);
  }
  100% {
    transform: translateY(0px);
  }
}

.floating-element {
  animation: float 3s ease-in-out infinite;
}

/* Morphing button */
.morph-button {
  background: #3498db;
  color: white;
  border: none;
  padding: 12px 24px;
  border-radius: 25px;
  cursor: pointer;
  transition: all 0.3s ease;
  overflow: hidden;
  position: relative;
}

.morph-button:hover {
  border-radius: 4px;
  padding: 12px 40px;
  background: #2980b9;
}

.morph-button::after {
  content: "→";
  position: absolute;
  right: 12px;
  top: 50%;
  transform: translateY(-50%) translateX(20px);
  opacity: 0;
  transition: all 0.3s ease;
}

.morph-button:hover::after {
  transform: translateY(-50%) translateX(0);
  opacity: 1;
}

/* Staggered animations */
.stagger-container {
  display: flex;
  gap: 10px;
}

.stagger-item {
  width: 20px;
  height: 20px;
  background: #e74c3c;
  border-radius: 50%;
  animation: bounce 0.6s ease-in-out infinite alternate;
}

.stagger-item:nth-child(1) {
  animation-delay: 0s;
}
.stagger-item:nth-child(2) {
  animation-delay: 0.1s;
}
.stagger-item:nth-child(3) {
  animation-delay: 0.2s;
}
.stagger-item:nth-child(4) {
  animation-delay: 0.3s;
}
.stagger-item:nth-child(5) {
  animation-delay: 0.4s;
}

5️⃣ Transform Property Deep Dive

/* 2D Transforms */
.transform-examples {
  /* Translation */
  transform: translateX(50px); /* Move horizontally */
  transform: translateY(-20px); /* Move vertically */
  transform: translate(50px, -20px); /* Move both directions */

  /* Scaling */
  transform: scaleX(1.5); /* Scale horizontally */
  transform: scaleY(0.8); /* Scale vertically */
  transform: scale(1.2); /* Scale uniformly */
  transform: scale(1.5, 0.8); /* Scale both directions */

  /* Rotation */
  transform: rotate(45deg); /* Rotate clockwise */
  transform: rotate(-30deg); /* Rotate counterclockwise */

  /* Skewing */
  transform: skewX(20deg); /* Skew horizontally */
  transform: skewY(-10deg); /* Skew vertically */
  transform: skew(20deg, -10deg); /* Skew both directions */

  /* Combined transforms */
  transform: translate(50px, 100px) rotate(45deg) scale(1.2);
}

/* 3D Transforms */
.transform-3d {
  /* 3D Translation */
  transform: translateZ(50px); /* Move in Z axis */
  transform: translate3d(50px, 100px, 25px); /* 3D translation */

  /* 3D Rotation */
  transform: rotateX(45deg); /* Rotate around X axis */
  transform: rotateY(60deg); /* Rotate around Y axis */
  transform: rotateZ(30deg); /* Rotate around Z axis */
  transform: rotate3d(1, 1, 0, 45deg); /* Rotate around custom axis */

  /* 3D Scaling */
  transform: scaleZ(2); /* Scale in Z direction */
  transform: scale3d(1.5, 1.2, 2); /* 3D scaling */

  /* Perspective */
  perspective: 1000px; /* Set 3D perspective */
  transform-style: preserve-3d; /* Preserve 3D for children */
}

/* Transform origin */
.transform-origin-examples {
  /* Default origin is center center */
  transform-origin: center center;

  /* Other origin points */
  transform-origin: top left;
  transform-origin: bottom right;
  transform-origin: 50% 25%;
  transform-origin: 10px 20px;

  /* 3D origin */
  transform-origin: center center 50px;
}

/* Practical 3D card flip */
.flip-card {
  background-color: transparent;
  width: 300px;
  height: 200px;
  perspective: 1000px;
}

.flip-card-inner {
  position: relative;
  width: 100%;
  height: 100%;
  text-align: center;
  transition: transform 0.6s;
  transform-style: preserve-3d;
}

.flip-card:hover .flip-card-inner {
  transform: rotateY(180deg);
}

.flip-card-front,
.flip-card-back {
  position: absolute;
  width: 100%;
  height: 100%;
  -webkit-backface-visibility: hidden;
  backface-visibility: hidden;
  border-radius: 12px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 18px;
  color: white;
}

.flip-card-front {
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
}

.flip-card-back {
  background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
  transform: rotateY(180deg);
}

/* 3D cube animation */
@keyframes rotateCube {
  0% {
    transform: rotateX(0deg) rotateY(0deg);
  }
  25% {
    transform: rotateX(90deg) rotateY(0deg);
  }
  50% {
    transform: rotateX(90deg) rotateY(90deg);
  }
  75% {
    transform: rotateX(0deg) rotateY(90deg);
  }
  100% {
    transform: rotateX(0deg) rotateY(0deg);
  }
}

.cube-container {
  perspective: 800px;
  width: 200px;
  height: 200px;
  margin: 100px auto;
}

.cube {
  position: relative;
  width: 200px;
  height: 200px;
  transform-style: preserve-3d;
  animation: rotateCube 4s infinite linear;
}

.cube-face {
  position: absolute;
  width: 200px;
  height: 200px;
  border: 2px solid #333;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 24px;
  font-weight: bold;
}

.cube-face.front {
  background: rgba(255, 0, 0, 0.7);
  transform: translateZ(100px);
}
.cube-face.back {
  background: rgba(0, 255, 0, 0.7);
  transform: rotateY(180deg) translateZ(100px);
}
.cube-face.right {
  background: rgba(0, 0, 255, 0.7);
  transform: rotateY(90deg) translateZ(100px);
}
.cube-face.left {
  background: rgba(255, 255, 0, 0.7);
  transform: rotateY(-90deg) translateZ(100px);
}
.cube-face.top {
  background: rgba(255, 0, 255, 0.7);
  transform: rotateX(90deg) translateZ(100px);
}
.cube-face.bottom {
  background: rgba(0, 255, 255, 0.7);
  transform: rotateX(-90deg) translateZ(100px);
}

6️⃣ Animation Performance and Best Practices

/* Hardware acceleration */
.gpu-accelerated {
  /* These properties trigger hardware acceleration */
  transform: translateZ(0);
  will-change: transform, opacity;

  /* Or use transform3d for the same effect */
  transform: translate3d(0, 0, 0);
}

/* Optimized animations - use transform and opacity */
.optimized-animation {
  /* ✅ Good - animates well */
  transition:
    transform 0.3s ease,
    opacity 0.3s ease;
}

.optimized-animation:hover {
  transform: translateY(-5px) scale(1.02);
  opacity: 0.9;
}

/* Avoid animating these properties */
.avoid-these {
  /* ❌ Bad - causes layout recalculation */
  /* transition: width 0.3s ease, height 0.3s ease; */
  /* transition: top 0.3s ease, left 0.3s ease; */
  /* transition: margin 0.3s ease, padding 0.3s ease; */
}

/* Use will-change for complex animations */
.complex-hover-card {
  will-change: transform;
  transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}

.complex-hover-card:hover {
  transform: translateY(-8px) rotateX(15deg) rotateY(5deg);
}

/* Remove will-change after animation */
.animation-complete {
  will-change: auto;
}

/* Reduced motion accessibility */
@media (prefers-reduced-motion: reduce) {
  .respectful-animation {
    animation: none;
    transition: none;
  }

  /* Provide alternative static states */
  .respectful-animation:hover {
    background-color: #e3f2fd;
    border-color: #2196f3;
  }
}

/* Container queries for responsive animations */
@container (min-width: 400px) {
  .container-aware-animation {
    animation-duration: 2s;
  }
}

@container (max-width: 399px) {
  .container-aware-animation {
    animation-duration: 1s;
  }
}

7️⃣ Complete Interactive Dashboard Project

This project demonstrates all the animation concepts in a practical, modern dashboard interface.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Animated Dashboard - CSS Animations Showcase</title>
    <style>
      * {
        margin: 0;
        padding: 0;
        box-sizing: border-box;
      }

      body {
        font-family:
          -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
        background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
        min-height: 100vh;
        padding: 20px;
      }

      .dashboard {
        max-width: 1200px;
        margin: 0 auto;
        animation: fadeInUp 1s ease both;
      }

      .header {
        background: rgba(255, 255, 255, 0.95);
        backdrop-filter: blur(10px);
        border-radius: 15px;
        padding: 25px;
        margin-bottom: 30px;
        box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
      }

      .header h1 {
        color: #333;
        font-size: 2rem;
        margin-bottom: 10px;
        animation: slideInFromLeft 0.8s ease 0.2s both;
      }

      .header p {
        color: #666;
        animation: slideInFromLeft 0.8s ease 0.4s both;
      }

      .stats-grid {
        display: grid;
        grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
        gap: 25px;
        margin-bottom: 30px;
      }

      .stat-card {
        background: rgba(255, 255, 255, 0.95);
        backdrop-filter: blur(10px);
        border-radius: 15px;
        padding: 25px;
        text-align: center;
        box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
        transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
        position: relative;
        overflow: hidden;
        animation: zoomIn 0.6s ease both;
      }

      .stat-card:nth-child(1) {
        animation-delay: 0.1s;
      }
      .stat-card:nth-child(2) {
        animation-delay: 0.2s;
      }
      .stat-card:nth-child(3) {
        animation-delay: 0.3s;
      }
      .stat-card:nth-child(4) {
        animation-delay: 0.4s;
      }

      .stat-card::before {
        content: "";
        position: absolute;
        top: 0;
        left: -100%;
        width: 100%;
        height: 100%;
        background: linear-gradient(
          90deg,
          transparent,
          rgba(255, 255, 255, 0.4),
          transparent
        );
        transition: left 0.6s ease;
      }

      .stat-card:hover {
        transform: translateY(-10px) scale(1.02);
        box-shadow: 0 20px 40px rgba(0, 0, 0, 0.15);
      }

      .stat-card:hover::before {
        left: 100%;
      }

      .stat-icon {
        width: 60px;
        height: 60px;
        margin: 0 auto 15px;
        background: linear-gradient(135deg, #667eea, #764ba2);
        border-radius: 15px;
        display: flex;
        align-items: center;
        justify-content: center;
        font-size: 24px;
        color: white;
        animation: pulse 2s infinite;
      }

      .stat-number {
        font-size: 2.5rem;
        font-weight: bold;
        color: #333;
        margin-bottom: 5px;
        counter-reset: number-counter;
        animation: countUp 2s ease-in-out;
      }

      .stat-label {
        color: #666;
        font-size: 0.9rem;
        text-transform: uppercase;
        letter-spacing: 1px;
      }

      .charts-section {
        display: grid;
        grid-template-columns: 2fr 1fr;
        gap: 25px;
        margin-bottom: 30px;
      }

      .chart-card {
        background: rgba(255, 255, 255, 0.95);
        backdrop-filter: blur(10px);
        border-radius: 15px;
        padding: 25px;
        box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
        animation: slideInFromBottom 0.8s ease 0.6s both;
      }

      .chart-title {
        font-size: 1.2rem;
        color: #333;
        margin-bottom: 20px;
        display: flex;
        align-items: center;
        gap: 10px;
      }

      .progress-bars {
        space-y: 15px;
      }

      .progress-item {
        margin-bottom: 20px;
      }

      .progress-label {
        display: flex;
        justify-content: space-between;
        margin-bottom: 8px;
        font-size: 0.9rem;
        color: #666;
      }

      .progress-bar {
        height: 8px;
        background: #e0e7ff;
        border-radius: 4px;
        overflow: hidden;
        position: relative;
      }

      .progress-fill {
        height: 100%;
        border-radius: 4px;
        position: relative;
        animation: progressLoad 2s ease-in-out;
      }

      .progress-fill::after {
        content: "";
        position: absolute;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        background: linear-gradient(
          90deg,
          transparent,
          rgba(255, 255, 255, 0.6),
          transparent
        );
        animation: progressShine 2s ease-in-out infinite;
      }

      .progress-fill.blue {
        background: linear-gradient(90deg, #3b82f6, #1d4ed8);
      }
      .progress-fill.green {
        background: linear-gradient(90deg, #10b981, #047857);
      }
      .progress-fill.purple {
        background: linear-gradient(90deg, #8b5cf6, #5b21b6);
      }
      .progress-fill.orange {
        background: linear-gradient(90deg, #f59e0b, #d97706);
      }

      .recent-activity {
        background: rgba(255, 255, 255, 0.95);
        backdrop-filter: blur(10px);
        border-radius: 15px;
        padding: 25px;
        box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
        animation: slideInFromRight 0.8s ease 0.8s both;
      }

      .activity-item {
        display: flex;
        align-items: center;
        gap: 15px;
        padding: 15px 0;
        border-bottom: 1px solid #f1f5f9;
        animation: fadeInLeft 0.6s ease both;
      }

      .activity-item:last-child {
        border-bottom: none;
      }

      .activity-item:nth-child(1) {
        animation-delay: 1s;
      }
      .activity-item:nth-child(2) {
        animation-delay: 1.1s;
      }
      .activity-item:nth-child(3) {
        animation-delay: 1.2s;
      }
      .activity-item:nth-child(4) {
        animation-delay: 1.3s;
      }

      .activity-icon {
        width: 40px;
        height: 40px;
        border-radius: 10px;
        display: flex;
        align-items: center;
        justify-content: center;
        color: white;
        font-size: 16px;
      }

      .activity-icon.success {
        background: linear-gradient(135deg, #10b981, #047857);
      }
      .activity-icon.warning {
        background: linear-gradient(135deg, #f59e0b, #d97706);
      }
      .activity-icon.info {
        background: linear-gradient(135deg, #3b82f6, #1d4ed8);
      }
      .activity-icon.error {
        background: linear-gradient(135deg, #ef4444, #dc2626);
      }

      .activity-content {
        flex: 1;
      }

      .activity-text {
        color: #333;
        font-size: 0.9rem;
        margin-bottom: 2px;
      }

      .activity-time {
        color: #666;
        font-size: 0.8rem;
      }

      .floating-action {
        position: fixed;
        bottom: 30px;
        right: 30px;
        width: 60px;
        height: 60px;
        background: linear-gradient(135deg, #667eea, #764ba2);
        border-radius: 50%;
        display: flex;
        align-items: center;
        justify-content: center;
        color: white;
        font-size: 24px;
        cursor: pointer;
        box-shadow: 0 8px 32px rgba(102, 126, 234, 0.3);
        animation: float 3s ease-in-out infinite;
        transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
      }

      .floating-action:hover {
        transform: scale(1.1);
        box-shadow: 0 12px 40px rgba(102, 126, 234, 0.4);
      }

      /* Keyframe Animations */
      @keyframes fadeInUp {
        from {
          opacity: 0;
          transform: translateY(30px);
        }
        to {
          opacity: 1;
          transform: translateY(0);
        }
      }

      @keyframes slideInFromLeft {
        from {
          opacity: 0;
          transform: translateX(-50px);
        }
        to {
          opacity: 1;
          transform: translateX(0);
        }
      }

      @keyframes slideInFromRight {
        from {
          opacity: 0;
          transform: translateX(50px);
        }
        to {
          opacity: 1;
          transform: translateX(0);
        }
      }

      @keyframes slideInFromBottom {
        from {
          opacity: 0;
          transform: translateY(50px);
        }
        to {
          opacity: 1;
          transform: translateY(0);
        }
      }

      @keyframes zoomIn {
        from {
          opacity: 0;
          transform: scale(0.3);
        }
        to {
          opacity: 1;
          transform: scale(1);
        }
      }

      @keyframes fadeInLeft {
        from {
          opacity: 0;
          transform: translateX(-30px);
        }
        to {
          opacity: 1;
          transform: translateX(0);
        }
      }

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

      @keyframes float {
        0%,
        100% {
          transform: translateY(0px);
        }
        50% {
          transform: translateY(-10px);
        }
      }

      @keyframes progressLoad {
        from {
          width: 0%;
        }
        to {
          width: var(--progress-width);
        }
      }

      @keyframes progressShine {
        0% {
          transform: translateX(-100%);
        }
        100% {
          transform: translateX(100%);
        }
      }

      @keyframes countUp {
        from {
          transform: scale(0.5);
          opacity: 0;
        }
        to {
          transform: scale(1);
          opacity: 1;
        }
      }

      /* Responsive Design */
      @media (max-width: 768px) {
        .charts-section {
          grid-template-columns: 1fr;
        }

        .stats-grid {
          grid-template-columns: 1fr;
        }

        .header h1 {
          font-size: 1.5rem;
        }

        .stat-number {
          font-size: 2rem;
        }
      }

      /* Reduced Motion */
      @media (prefers-reduced-motion: reduce) {
        * {
          animation-duration: 0.01ms !important;
          animation-iteration-count: 1 !important;
          transition-duration: 0.01ms !important;
        }
      }
    </style>
  </head>
  <body>
    <div class="dashboard">
      <!-- Header -->
      <div class="header">
        <h1>Analytics Dashboard</h1>
        <p>Welcome back! Here's what's happening with your projects today.</p>
      </div>

      <!-- Statistics Cards -->
      <div class="stats-grid">
        <div class="stat-card">
          <div class="stat-icon">📊</div>
          <div class="stat-number">15,847</div>
          <div class="stat-label">Total Views</div>
        </div>
        <div class="stat-card">
          <div class="stat-icon">👥</div>
          <div class="stat-number">3,296</div>
          <div class="stat-label">Active Users</div>
        </div>
        <div class="stat-card">
          <div class="stat-icon">💰</div>
          <div class="stat-number">$12,847</div>
          <div class="stat-label">Revenue</div>
        </div>
        <div class="stat-card">
          <div class="stat-icon">📈</div>
          <div class="stat-number">23.5%</div>
          <div class="stat-label">Growth Rate</div>
        </div>
      </div>

      <!-- Charts Section -->
      <div class="charts-section">
        <div class="chart-card">
          <div class="chart-title">📊 Performance Metrics</div>
          <div class="progress-bars">
            <div class="progress-item">
              <div class="progress-label">
                <span>Website Traffic</span>
                <span>85%</span>
              </div>
              <div class="progress-bar">
                <div
                  class="progress-fill blue"
                  style="--progress-width: 85%;"
                ></div>
              </div>
            </div>
            <div class="progress-item">
              <div class="progress-label">
                <span>User Engagement</span>
                <span>72%</span>
              </div>
              <div class="progress-bar">
                <div
                  class="progress-fill green"
                  style="--progress-width: 72%;"
                ></div>
              </div>
            </div>
            <div class="progress-item">
              <div class="progress-label">
                <span>Conversion Rate</span>
                <span>91%</span>
              </div>
              <div class="progress-bar">
                <div
                  class="progress-fill purple"
                  style="--progress-width: 91%;"
                ></div>
              </div>
            </div>
            <div class="progress-item">
              <div class="progress-label">
                <span>Customer Satisfaction</span>
                <span>68%</span>
              </div>
              <div class="progress-bar">
                <div
                  class="progress-fill orange"
                  style="--progress-width: 68%;"
                ></div>
              </div>
            </div>
          </div>
        </div>

        <div class="recent-activity">
          <div class="chart-title">🔔 Recent Activity</div>
          <div class="activity-item">
            <div class="activity-icon success">✓</div>
            <div class="activity-content">
              <div class="activity-text">New user registered</div>
              <div class="activity-time">2 minutes ago</div>
            </div>
          </div>
          <div class="activity-item">
            <div class="activity-icon warning">⚠</div>
            <div class="activity-content">
              <div class="activity-text">Server load high</div>
              <div class="activity-time">5 minutes ago</div>
            </div>
          </div>
          <div class="activity-item">
            <div class="activity-icon info">ℹ</div>
            <div class="activity-content">
              <div class="activity-text">Database backup completed</div>
              <div class="activity-time">1 hour ago</div>
            </div>
          </div>
          <div class="activity-item">
            <div class="activity-icon error">✕</div>
            <div class="activity-content">
              <div class="activity-text">Payment failed</div>
              <div class="activity-time">2 hours ago</div>
            </div>
          </div>
        </div>
      </div>
    </div>

    <!-- Floating Action Button -->
    <div class="floating-action">+</div>

    <script>
      // Add interactive functionality
      document.addEventListener("DOMContentLoaded", function () {
        // Animate numbers counting up
        const numbers = document.querySelectorAll(".stat-number");
        numbers.forEach((number) => {
          const finalValue = number.textContent.replace(/[^0-9.]/g, "");
          if (!isNaN(finalValue)) {
            animateNumber(number, 0, parseFloat(finalValue), 2000);
          }
        });

        // Add click interactions
        const statCards = document.querySelectorAll(".stat-card");
        statCards.forEach((card) => {
          card.addEventListener("click", function () {
            this.style.animation = "pulse 0.6s ease";
            setTimeout(() => {
              this.style.animation = "";
            }, 600);
          });
        });

        // Floating action button interaction
        const fab = document.querySelector(".floating-action");
        fab.addEventListener("click", function () {
          this.style.animation = "bounce 0.6s ease";
          setTimeout(() => {
            this.style.animation = "float 3s ease-in-out infinite";
          }, 600);
        });
      });

      function animateNumber(element, start, end, duration) {
        const startTime = performance.now();
        const originalText = element.textContent;

        function updateNumber(currentTime) {
          const elapsed = currentTime - startTime;
          const progress = Math.min(elapsed / duration, 1);

          const currentValue = start + (end - start) * easeOutQuart(progress);
          element.textContent = originalText.replace(
            /[0-9.]+/,
            Math.floor(currentValue).toLocaleString()
          );

          if (progress < 1) {
            requestAnimationFrame(updateNumber);
          }
        }

        requestAnimationFrame(updateNumber);
      }

      function easeOutQuart(t) {
        return 1 - Math.pow(1 - t, 4);
      }
    </script>
  </body>
</html>

Summary

In this lesson we learned:

CSS Transitions fundamentalsKeyframe Animations and timing functionsTransform properties and 3D effectsAdvanced animation techniquesPerformance optimization best practicesComplete interactive dashboard project

In the next lesson we'll study CSS Grid Advanced Techniques and Complex Layouts.

📩 Need help with Animations?

aboutservicesprojectsBlogscontact