Bài 19. Animation với @keyframes

Khác với transition chỉ chạy khi trạng thái đổi, animation có thể tự chạy, lặp lại và gồm nhiều bước. Bài này học @keyframes, các thuộc tính animation và tạo các hiệu ứng thường gặp: tải trang, nhấp nháy, xoay, xuất hiện khi cuộn.

45 phútTrung cấp
Bạn sẽ học được
  • Viết @keyframes với from/to và phần trăm
  • Dùng animation-name, duration, delay, iteration, direction, fill-mode
  • Tạo loader, hiệu ứng xuất hiện, chạy chữ
  • Điều khiển bằng animation-play-state và scroll-driven animation

Một số khái niệm

Thuộc tínhVí dụÝ nghĩa
animation-namexuat-hienTên @keyframes
animation-duration0.6sThời lượng một lần
animation-timing-functionease-outĐường cong tốc độ
animation-delay.2sĐộ trễ
animation-iteration-count3 | infiniteSố lần lặp
animation-directionalternateChạy xuôi rồi ngược
animation-fill-modeboth | forwardsGiữ trạng thái đầu/cuối
animation (viết tắt)xuat-hien .6s ease-out .2s both

Các hiệu ứng thường gặp

<style>
  @keyframes xoay { to { transform: rotate(360deg); } }
  @keyframes nhip { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.15); } }
  @keyframes hien { from { opacity: 0; transform: translateY(16px); } to { opacity: 1; transform: none; } }
  @keyframes cham { 0%, 80%, 100% { opacity: .2; } 40% { opacity: 1; } }
  .loader { width: 34px; height: 34px; border: 4px solid #c8e6c9; border-top-color: #2e7d32; border-radius: 50%; animation: xoay .8s linear infinite; display: inline-block; }
  .tim { display: inline-block; font-size: 30px; color: #e53935; animation: nhip 1s ease-in-out infinite; margin: 0 20px; }
  .the { padding: 10px; background: #e3f2fd; border-radius: 8px; margin: 6px 0; animation: hien .6s ease-out both; }
  .the:nth-child(2) { animation-delay: .2s; } .the:nth-child(3) { animation-delay: .4s; }
  .ch span { display: inline-block; width: 10px; height: 10px; margin: 2px; border-radius: 50%; background: #1565c0; animation: cham 1.2s infinite; }
  .ch span:nth-child(2) { animation-delay: .2s; } .ch span:nth-child(3) { animation-delay: .4s; }
</style>
<div class="loader"></div><span class="tim">♥</span><span class="ch"><span></span><span></span><span></span></span>
<div><div class="the">Thẻ 1 xuất hiện</div><div class="the">Thẻ 2 (trễ .2s)</div><div class="the">Thẻ 3 (trễ .4s)</div></div>
Kết quả hiển thị

Tạm dừng khi rê chuột, chạy chữ

<style>
  @keyframes chay { from { transform: translateX(100%); } to { transform: translateX(-100%); } }
  .bang-tin { overflow: hidden; background: #263238; color: #fff; padding: 8px 0; border-radius: 6px; }
  .bang-tin p { margin: 0; white-space: nowrap; animation: chay 12s linear infinite; }
  .bang-tin:hover p { animation-play-state: paused; }
</style>
<div class="bang-tin"><p>📢 Loạt bài Bootstrap 5 và Tailwind CSS vừa ra mắt trên Tự Học Tin · Rê chuột để dừng</p></div>
Kết quả hiển thị

Animation theo thanh cuộn (scroll-driven)

/* Thanh tiến độ đọc bài chạy theo thanh cuộn trang, không cần JavaScript */
@keyframes tien-do { from { transform: scaleX(0); } to { transform: scaleX(1); } }
.thanh-doc {
  position: fixed; top: 0; left: 0; right: 0; height: 4px; background: #2e7d32;
  transform-origin: left;
  animation: tien-do linear;
  animation-timeline: scroll();       /* gắn với thanh cuộn tài liệu */
}
/* Phần tử hiện dần khi cuộn vào khung nhìn */
.hien-khi-cuon { animation: hien linear both; animation-timeline: view(); animation-range: entry 0% cover 30%; }

Scroll-driven animation được Chrome, Edge hỗ trợ; trình duyệt chưa hỗ trợ sẽ bỏ qua và phần tử vẫn hiển thị bình thường.

Mẹo hay

Thư viện Animate.css cung cấp sẵn hàng chục @keyframes; đọc mã nguồn của nó là cách học animation rất tốt.

Lưu ý

Animation vô hạn chạy liên tục làm phân tán sự chú ý và hao pin; chỉ dùng cho trạng thái chờ tải hoặc điểm nhấn thật cần thiết.

Thực hành
  1. Làm biểu tượng tải dữ liệu xoay tròn.
  2. Cho 4 thẻ khóa học xuất hiện lần lượt khi tải trang.
  3. Làm băng chữ chạy thông báo dừng khi rê chuột.
  4. Thêm thanh tiến độ đọc bài bằng scroll-driven animation.
Tóm tắt bài học
  • @keyframes định nghĩa các bước; animation gắn vào phần tử.
  • duration, delay, iteration-count, direction, fill-mode.
  • animation-play-state để tạm dừng.
  • animation-timeline: scroll()/view() cho hiệu ứng theo cuộn.