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.
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ính | Ví dụ | Ý nghĩa |
|---|---|---|
| animation-name | xuat-hien | Tên @keyframes |
| animation-duration | 0.6s | Thời lượng một lần |
| animation-timing-function | ease-out | Đường cong tốc độ |
| animation-delay | .2s | Độ trễ |
| animation-iteration-count | 3 | infinite | Số lần lặp |
| animation-direction | alternate | Chạy xuôi rồi ngược |
| animation-fill-mode | both | forwards | Giữ 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
- Làm biểu tượng tải dữ liệu xoay tròn.
- Cho 4 thẻ khóa học xuất hiện lần lượt khi tải trang.
- Làm băng chữ chạy thông báo dừng khi rê chuột.
- 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.