ToolHub
View All Posts

คู่มือ CSS Animation: Transition, Keyframes และประสิทธิภาพ

CSS Animation เติมชีวิตชีวาให้กับอินเทอร์เฟซ ให้การตอบสนองทางภาพ นำทางความสนใจของผู้ใช้ และสร้างประสบการณ์ที่น่าจดจำ Animation ที่ทำได้ดีรู้สึกเป็นธรรมชาติและเข้าใจง่าย Animation ที่ทำได้ไม่ดีนำไปสู่การกระตุก ดึงความสนใจของผู้ใช้ และอาจทำให้เกิดความไม่สบายทางกาย คู่มือนี้ครอบคลุมทุกอย่างตั้งแต่พื้นฐานของ Transition และ Keyframes ไปจนถึงการปรับแต่งประสิทธิภาพขั้นสูงและการเข้าถึง เพื่อให้คุณมีความรู้ในการสร้าง Animation ที่ลื่นไหล มีจุดมุ่งหมาย และครอบคลุม

CSS Transition กับ Animation

CSS มีกลไกสองแบบที่แตกต่างกันสำหรับการสร้าง Animation: Transition และ Animation การเข้าใจว่าเมื่อใดควรใช้แต่ละแบบเป็นพื้นฐานสำหรับการทำงานกับ CSS Animation อย่างมีประสิทธิภาพ

CSS Transition

Transition เพิ่ม Animation ให้กับการเปลี่ยนแปลงระหว่างสองสถานะของคุณสมบัติ CSS คุณกำหนดคุณสมบัติที่จะ animate ระยะเวลาของ Animation และเส้นโค้ง easing เบราว์เซอร์จะจัดการการประมาณค่าระหว่างค่าเริ่มต้นและค่าสิ้นสุดโดยอัตโนมัติ Transition ถูกเรียกโดยการเปลี่ยนแปลงสถานะ เช่น hover, focus, การเพิ่มคลาส หรือการเปลี่ยนแปลงคุณสมบัติด้วย JavaScript

.button {
  background: #3b82f6;
  transform: scale(1);
  transition: background 0.3s ease, transform 0.2s ease;
}

.button:hover {
  background: #2563eb;
  transform: scale(1.05);
}

Transition เหมาะสำหรับ Animation สองสถานะที่เรียบง่าย พวกมันต้องการโค้ดน้อยที่สุด เข้าใจง่าย และทำงานได้อย่างน่าเชื่อถือในเบราว์เซอร์ ข้อจำกัดคือพวกมัน animate ระหว่างสองค่าเท่านั้น — คุณไม่สามารถกำหนดขั้นตอนกลางได้

CSS Animation (Keyframes)

Animation ใช้กฎ @keyframes เพื่อกำหนดลำดับการเปลี่ยนแปลงสไตล์ในจำนวนขั้นตอนเท่าใดก็ได้ ซึ่งแตกต่างจาก Transition Animation สามารถทำงานโดยอิสระจากการเปลี่ยนแปลงสถานะ วนซ้ำไม่จำกัด เล่นย้อนกลับ และหยุดชั่วคราว พวกมันให้คุณควบคุมแต่ละเฟรมของ Animation ได้อย่างแม่นยำ

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

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

เมื่อใดควรใช้แบบไหน

สถานการณ์ใช้ Transitionใช้ Animation
เอฟเฟกต์ Hoverใช่ไม่
สถานะ Focusใช่ไม่
สลับการมองเห็นใช่อาจจะ
ลำดับหลายขั้นตอนไม่ใช่
Animation แบบวนซ้ำไม่ใช่
อิสระจากสถานะไม่ใช่
Animation การเข้าอาจจะใช่

เจาะลึกไวยากรณ์ Keyframes

กฎ @keyframes เป็นหัวใจของ CSS Animation การเข้าใจไวยากรณ์อย่างถ่องแท้จะปลดปล่อยพลังเต็มที่ของลำดับ Animation หลายขั้นตอน

Keyframes แบบเปอร์เซ็นต์

Keyframes ถูกกำหนดโดยใช้ค่าเปอร์เซ็นต์ตั้งแต่ 0% ถึง 100% แสดงถึงความคืบหน้าบนไทม์ไลน์ของ Animation คุณสามารถกำหนด Keyframes ได้มากเท่าที่ต้องการ และเบราว์เซอร์จะประมาณค่าระหว่างพวกมัน:

@keyframes bounce {
  0%, 100% {
    transform: translateY(0);
  }
  25% {
    transform: translateY(-20px);
  }
  50% {
    transform: translateY(0);
  }
  75% {
    transform: translateY(-10px);
  }
}

Keyframes หลายตัวสามารถใช้บล็อกสไตล์เดียวกันได้โดยการคั่นค่าเปอร์เซ็นต์ด้วยเครื่องหมายจุลภาค เช่น 0%, 100% ในตัวอย่างข้างต้น สิ่งนี้มีประโยชน์สำหรับ Animation ที่กลับสู่สถานะเริ่มต้น

คุณสมบัติย่อ Animation

คุณสมบัติย่อ animation รวมคุณสมบัติย่อยแปดรายการเข้าเป็นประกาศเดียว ลำดับคือ: name, duration, timing-function, delay, iteration-count, direction, fill-mode และ play-state

.element {
  animation: slideIn 0.5s ease-out 0.2s 1 forwards running;
}

/* Equivalent longhand */
.element {
  animation-name: slideIn;
  animation-duration: 0.5s;
  animation-timing-function: ease-out;
  animation-delay: 0.2s;
  animation-iteration-count: 1;
  animation-direction: normal;
  animation-fill-mode: forwards;
  animation-play-state: running;
}

โหมดการเติม Animation

คุณสมบัติ animation-fill-mode ควบคุมว่าสไตล์ใดจะถูกใช้ก่อนและหลังการทำงานของ Animation นี่เป็นหนึ่งในคุณสมบัติ Animation ที่ถูกเข้าใจผิดบ่อยที่สุด:

ฟังก์ชัน Easing

ฟังก์ชัน easing (หรือที่เรียกว่าฟังก์ชัน timing) กำหนดเส้นโค้งการเร่งของ Animation พวกมันกำหนดว่า Animation เริ่มช้าแล้วเร่งขึ้น เริ่มเร็วแล้วลดความเร็วลง หรือทำตามรูปแบบที่ซับซ้อนมากขึ้น ฟังก์ชัน easing ที่ถูกต้องทำให้ Animation รู้สึกเป็นธรรมชาติ ฟังก์ชัน easing ที่ผิดทำให้ Animation รู้สึกเป็นกลไกหรือแข็งกระด้าง

ฟังก์ชัน Easing ในตัว

เส้นโค้ง Cubic Bezier

ฟังก์ชัน cubic-bezier() ให้คุณกำหนดเส้นโค้ง easing แบบกำหนดเองผ่านจุดควบคุมที่แม่นยำ มันรับพารามิเตอร์สี่ตัวที่แสดงจุดควบคุมของเส้นโค้ง cubic bezier: cubic-bezier(x1, y1, x2, y2) ค่า x แสดงเวลา (0 ถึง 1) ค่า y แสดงความคืบหน้า (สามารถเกิน 0-1 เพื่อสร้างเอฟเฟกต์ overshoot)

.element {
  /* Smooth deceleration - great for entrances */
  transition: transform 0.3s cubic-bezier(0.0, 0.0, 0.2, 1.0);

  /* Smooth acceleration - great for exits */
  transition: transform 0.2s cubic-bezier(0.4, 0.0, 1, 1);

  /* Material Design standard easing */
  transition: transform 0.3s cubic-bezier(0.4, 0.0, 0.2, 1);
}

ฟังก์ชันขั้นบันได

ฟังก์ชัน steps() สร้าง Animation แบบเฟรมต่อเฟรมที่ไม่ต่อเนื่อง แทนที่จะประมาณค่าอย่างราบรื่น สิ่งนี้มีประโยชน์สำหรับ Animation สไปรต์หรือการสร้างเอฟเฟกต์ "การพิมพ์":

@keyframes typing {
  from { width: 0; }
  to { width: 100%; }
}

.typing-effect {
  animation: typing 3s steps(40, end);
  overflow: hidden;
  white-space: nowrap;
}

การปรับแต่งประสิทธิภาพ

Animation ที่ลื่นไหลต้องการ 60 เฟรมต่อวินาที (fps) ซึ่งหมายความว่าแต่ละเฟรมต้องเสร็จสิ้นภายใน 16.67 มิลลิวินาที การไม่สามารถตอบสนองงบประมาณนี้นำไปสู่การกระตุกที่มองเห็นได้ — ภาพกระตุก เฟรมหาย และประสบการณ์ผู้ใช้ที่แย่ลง การเข้าใจไปป์ไลน์การเรนเดอร์ของเบราว์เซอร์เป็นกุญแจสำคัญในการเขียน Animation ที่มีประสิทธิภาพสูง

ไปป์ไลน์การเรนเดอร์

เมื่อคุณสมบัติ CSS เปลี่ยนแปลง เบราว์เซอร์จะผ่านขั้นตอนสูงสุดสามขั้นตอนเพื่ออัปเดตการแสดงผล:

  1. Style: กำหนดว่ากฎ CSS ใดใช้กับองค์ประกอบใด
  2. Layout: คำนวณขนาดและตำแหน่งของแต่ละองค์ประกอบ ถูกเรียกโดยการเปลี่ยนแปลงของ width, height, margin, padding, top, left, font-size และคุณสมบัติทางเรขาคณิตอื่นๆ
  3. Paint: เติมพิกเซลสำหรับแต่ละองค์ประกอบ ถูกเรียกโดยการเปลี่ยนแปลงของ color, background, box-shadow, border-radius และคุณสมบัติทางภาพอื่นๆ
  4. Composite: รวมเลเยอร์ที่ถูก Paint แล้วในลำดับที่ถูกต้อง เฉพาะขั้นตอนนี้ที่ทำงานบน GPU ถูกเรียกโดยการเปลี่ยนแปลงของ transform และ opacity

Animation ที่เรียกเฉพาะขั้นตอน Composite เท่านั้นมีประสิทธิภาพดีที่สุด เพราะพวกมันข้าม Layout และ Paint อย่างสมบูรณ์ นี่คือเหตุผลที่ transform และ opacity เป็นมาตรฐานทองคำสำหรับ CSS Animation ที่มีประสิทธิภาพสูง

คุณสมบัติ Compositor-Only

คุณสมบัติเรียก Layout?เรียก Paint?GPU Composite?
transformไม่ไม่ใช่
opacityไม่ไม่ใช่
filterไม่ใช่บางครั้ง
top / leftใช่ใช่ไม่
width / heightใช่ใช่ไม่
margin / paddingใช่ใช่ไม่
background-colorไม่ใช่ไม่
box-shadowไม่ใช่ไม่

การใช้ will-change

คุณสมบัติ will-change บอกเบราว์เซอร์ว่าคุณสมบัติใดที่คาดว่าจะเปลี่ยนแปลง อนุญาตให้มันเพิ่มประสิทธิภาพล่วงหน้าโดยการย้ายองค์ประกอบไปยังเลเยอร์ compositor ของตัวเอง อย่างไรก็ตาม ควรใช้อย่างระมัดระวัง:

/* Apply will-change just before the animation */
.element:hover {
  will-change: transform;
}

/* Remove it after the animation completes */
.element {
  transition: transform 0.3s ease;
}

ข้อผิดพลาดทั่วไปของ will-change รวมถึงการใช้กับองค์ประกอบมากเกินไป (แต่ละเลเยอร์ compositor ใช้หน่วยความจำ GPU) และการเก็บไว้ถาวร (สิ้นเปลืองทรัพยากร) แนวปฏิบัติที่ดีคือการเพิ่ม will-change ผ่าน JavaScript ก่อนที่ Animation จะเริ่ม และลบออกหลังจาก Animation สิ้นสุด

ใช้ Transform แทนคุณสมบัติ Layout

การปรับแต่งประสิทธิภาพที่มีประสิทธิภาพที่สุดคือการแทนที่คุณสมบัติที่เรียก Layout ด้วย transform:

กฎประสิทธิภาพ: หากคุณสามารถบรรลุเอฟเฟกต์ภาพเดียวกันด้วย transform หรือ opacity ให้ใช้พวกมันแทนคุณสมบัติที่เรียก Layout หรือ Paint เสมอ หลักการนี้สามารถกำจัดปัญหาประสิทธิภาพ Animation ส่วนใหญ่ได้

รูปแบบ Animation ที่พบบ่อย

รูปแบบ Animation บางอย่างปรากฏซ้ำๆ ในอินเทอร์เฟซเว็บ การเชี่ยวชาญรูปแบบเหล่านี้ให้ชุดเครื่องมือสำหรับความต้องการ Animation UI ทั่วไปส่วนใหญ่

1. Fade In

Animation การเข้าแบบง่ายและหลากหลายที่สุด องค์ประกอบเปลี่ยนจากโปร่งใสเป็นทึบ:

@keyframes fadeIn {
  from { opacity: 0; }
  to { opacity: 1; }
}

.fade-in {
  animation: fadeIn 0.4s ease-out forwards;
}

2. Slide Up และ Fade In

เอฟเฟกต์การเข้าแบบไดนามิกมากขึ้น ผสมการเคลื่อนที่แนวตั้งกับการเปลี่ยนแปลงความโปร่งใส สิ่งนี้สร้างความรู้สึกว่าองค์ประกอบมาถึงจากด้านล่าง:

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

.slide-up {
  animation: slideUpFade 0.5s cubic-bezier(0.4, 0, 0.2, 1) forwards;
}

3. Hover Scale

การขยายขนาดเล็กน้อยเมื่อ hover ให้การตอบสนองการโต้ตอบที่น่าพอใจ:

.card {
  transition: transform 0.2s ease, box-shadow 0.2s ease;
}

.card:hover {
  transform: translateY(-4px) scale(1.02);
  box-shadow: 0 12px 24px rgba(0, 0, 0, 0.15);
}

4. Staggered List Animation

เมื่อรายการปรากฏขึ้น การตั้งค่า animation-delay แบบเหลื่อมสำหรับแต่ละรายการสร้างเอฟเฟกต์แบบน้ำตกที่นำทางสายตา:

.list-item {
  opacity: 0;
  transform: translateY(10px);
  animation: slideUpFade 0.3s ease-out forwards;
}

.list-item:nth-child(1) { animation-delay: 0.0s; }
.list-item:nth-child(2) { animation-delay: 0.05s; }
.list-item:nth-child(3) { animation-delay: 0.1s; }
.list-item:nth-child(4) { animation-delay: 0.15s; }
.list-item:nth-child(5) { animation-delay: 0.2s; }

สำหรับรายการแบบไดนามิก ใช้ JavaScript เพื่อตั้งค่า animation-delay ตามดัชนีของแต่ละรายการ หรือใช้ CSS custom properties: style="animation-delay: calc(var(--i) * 0.05s)"

5. Loading Spinner

การหมุนต่อเนื่องที่ราบรื่นเป็นตัวบ่งชี้การโหลดแบบคลาสสิก:

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

.spinner {
  width: 24px;
  height: 24px;
  border: 3px solid rgba(255, 255, 255, 0.2);
  border-top-color: #3b82f6;
  border-radius: 50%;
  animation: spin 0.8s linear infinite;
}

การเข้าถึง Animation: prefers-reduced-motion

ไม่ใช่ผู้ใช้ทุกคนที่ได้ประโยชน์จาก Animation สำหรับผู้ที่มีความผิดปกติของระบบการทรงตัว ความไวต่อการเคลื่อนไหว หรือสภาวะทางการรับรู้บางอย่าง Animation อาจทำให้เกิดอาการเวียนศีรษะ คลื่นไส้ หรือชักได้ media query prefers-reduced-motion อนุญาตให้คุณเคารพการตั้งค่าระบบของผู้ใช้ในการลด Animation

การนำ Animation แบบลดมาใช้

วิธีการที่แนะนำคือการเปิดใช้งาน Animation สำหรับผู้ใช้ที่ไม่ได้ตั้งค่าการลด Animation:

/* Default: no animation for users who prefer reduced motion */
.element {
  opacity: 1;
  transform: none;
}

/* Only animate for users who have no motion preference */
@media (prefers-reduced-motion: no-preference) {
  .element {
    animation: slideUpFade 0.5s ease-out forwards;
  }
}

อีกทางเลือกหนึ่ง คุณสามารถปิดการใช้งาน Animation เฉพาะสำหรับผู้ใช้ที่ต้องการลด Animation:

.element {
  animation: slideUpFade 0.5s ease-out forwards;
}

@media (prefers-reduced-motion: reduce) {
  .element {
    animation: none;
    opacity: 1;
    transform: none;
  }

  /* Keep functional transitions but shorten duration */
  * {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }
}

สิ่งใดควรเก็บและสิ่งใดควรลบออก

เมื่อผู้ใช้ต้องการลด Animation ไม่ควรลบ Animation ทั้งหมดออก Animation ที่ทำหน้าที่สื่อความหมายหรือสถานะควรเก็บไว้ แต่ทำให้เรียบง่ายขึ้น:

ไลบรารี Animation

ในขณะที่ CSS Animation จัดการความต้องการ UI ส่วนใหญ่ ไลบรารี JavaScript Animation มีคุณสมบัติขั้นสูงเช่นการเคลื่อนที่ตามฟิสิกส์ Animation ที่เชื่อมโยงกับการเลื่อน และการจัดการลำดับที่ซับซ้อน

ไลบรารีที่เน้น CSS

ไลบรารี JavaScript Animation

เมื่อใดควรใช้ JavaScript เทียบกับ CSS

CSS สำหรับ Animation แบบประกาศที่เรียบง่ายที่ตอบสนองต่อการเปลี่ยนแปลงสถานะ JavaScript สำหรับ: การเคลื่อนที่ตามฟิสิกส์ (สปริง, โมเมนตัม), Animation ที่เชื่อมโยงกับการเลื่อน, ลำดับที่ซับซ้อนที่มีการควบคุมเวลาที่แม่นยำ, พารามิเตอร์ Animation แบบไดนามิกที่คำนวณตอนรันไทม์ หรือ Animation ที่ต้องหยุดชั่วคราว ย้อนกลับ หรือลากด้วยการเขียนโปรแกรม

การดีบัก Animation

บั๊ก Animation อาจละเอียดอ่อนและยากต่อการวินิจฉัย เครื่องมือและเทคนิคการดีบักที่ถูกต้องทำให้กระบวนการมีประสิทธิภาพมากขึ้น

แผง Animation ใน Chrome DevTools

Chrome DevTools มีแผง Animation เฉพาะที่ให้ความสามารถในการดีบักที่ทรงพลัง:

การวิเคราะห์ประสิทธิภาพ

ใช้แผง Performance ใน Chrome DevTools เพื่อระบุการกระตุกของ Animation:

สถานการณ์การดีบักที่พบบ่อย

กำลังใช้ CSS อยู่หรือเปล่า? ลองใช้เครื่องมือ CSS ฟรีของเราเพื่อจัดรูปแบบ ย่อ และปรับแต่งสไตล์ชีตของคุณสำหรับการใช้งานจริง

เครื่องมือจัดรูปแบบ CSSเครื่องมือบีบอัด CSS

คำถามที่พบบ่อย

ควรใช้ CSS Transition หรือ CSS Animation?

CSS Transition ใช้สำหรับการเปลี่ยนแปลงสถานะอย่างง่ายจากจุด A ไปจุด B เช่น เอฟเฟกต์ hover, สถานะ focus และการสลับการมองเห็น CSS Animation (Keyframes) ใช้สำหรับลำดับหลายขั้นตอนที่ซับซ้อน, Animation แบบวนซ้ำ หรือ Animation ที่ต้องทำงานโดยอิสระจากการเปลี่ยนแปลงสถานะ Transition ง่ายกว่า; Animation ให้การควบคุมมากกว่า

คุณสมบัติ CSS ใดที่ปลอดภัยสำหรับ Animation เพื่อประสิทธิภาพ?

คุณสมบัติที่มีประสิทธิภาพ Animation ดีที่สุดคือ transform และ opacity เพราะสามารถจัดการโดย GPU compositor ทั้งหมด โดยไม่ต้องเรียก Layout หรือ Paint คุณสมบัติอื่นๆ เช่น width, height, margin และ top เรียกการคำนวณ Layout ใหม่ ซึ่งมีค่าใช้จ่ายสูง ใช้ transform: translateX() แทน left และ transform: scale() แทนการเปลี่ยนแปลง width/height เสมอ

จะให้การช่วยเหลือการเข้าถึงสำหรับผู้ใช้ที่ไวต่อ Animation ได้อย่างไร?

ใช้ media query prefers-reduced-motion เพื่อปิดหรือลดความซับซ้อนของ Animation สำหรับผู้ใช้ที่เปิดการตั้งค่า "ลด Animation" ในระบบปฏิบัติการ ห่อ Animation ที่ไม่จำเป็นใน @media (prefers-reduced-motion: no-preference) และให้การเปลี่ยนแปลงสถานะทันทีเป็นตัวเลือกสำรองสำหรับผู้ใช้ที่ต้องการลด Animation

will-change คืออะไรและควรใช้เมื่อใด?

will-change เป็นคุณสมบัติ CSS ที่บอกใบ้เบราว์เซอร์ว่าคุณสมบัติใดจะเปลี่ยนแปลงในอนาคต อนุญาตให้มันเพิ่มประสิทธิภาพล่วงหน้า ใช้อย่างระมัดระวัง เฉพาะเมื่อสังเกตเห็นปัญหาด้านประสิทธิภาพ ใช้ก่อน Animation เริ่ม และลบออกหลังจาก Animation สิ้นสุด การใช้ will-change มากเกินไปสิ้นเปลืองหน่วยความจำ GPU และอาจส่งผลเสียต่อประสิทธิภาพ

จะดีบัก CSS Animation ได้อย่างไร?

Chrome DevTools มีเครื่องมือดีบัก Animation ที่ทรงพลัง เปิดแผง Animation (ในเมนู More Tools) เพื่อดู Animation ที่ทำงานอยู่ทั้งหมด ลากไทม์ไลน์ แก้ไขระยะเวลาและดีเลย์แบบเรียลไทม์ ลดความเร็ว Animation ลงเหลือ 1/4 คุณยังสามารถใช้แผง Performance เพื่อระบุการกระตุกของ Animation และ Layout Thrashing