Các hàm easing CSS truyền thống như ease-in hoặc cubic-bezier() chỉ giới hạn ở các đường cong đơn giản, nên không thể tạo ra các hiệu ứng phức tạp dựa trên vật lý như nảy hoặc lò xo. Hàm thời gian linear() giải quyết vấn đề này bằng cách cho phép bạn cung cấp một loạt điểm dừng có thể ước chừng các đường cong phức tạp. Hiệu ứng chuyển tiếp và ảnh động được nội suy dựa trên các đường thẳng giữa các điểm dừng, nhưng trong đủ điểm dừng, hiệu ứng này có thể xuất hiện mượt mà.
Các bước triển khai
- Tạo điểm dừng đường cong:
Việc vẽ thủ công hàng chục điểm cho hiệu ứng lò xo hoặc nảy là không thực tế. Sử dụng hàm thời gian từ thư viện bên ngoài hoặc dùng một công cụ để chuyển đổi hàm easing JavaScript hiện có hoặc đường dẫn SVG thành cú pháp
linear(). Không bắt buộc: lưu trữ các hàm thời gian này dưới dạng thuộc tính tuỳ chỉnh CSS để sử dụng lại trên toàn bộ trang web. - Xác định hàm thời gian:
Áp dụng các điểm dừng đã tạo cho thuộc tính
transition-timing-functionhoặcanimation-timing-function, hoặc thông qua các ký hiệu viết tắttransitionhoặcanimation. - Điều chỉnh thời lượng:
Không giống như các công cụ vật lý JavaScript (trong đó thời lượng được lấy từ các thuộc tính vật lý như khối lượng, độ cứng), CSS vẫn yêu cầu một
durationcố định. Bạn có thể cần điều chỉnh thời lượng để đạt được hiệu ứng mong muốn.
Ví dụ: Spring Easing
Ví dụ này cho thấy cách sử dụng hàm linear() tuỳ chỉnh để tạo hiệu ứng lò xo vượt quá giá trị mục tiêu trước khi ổn định.
.spring {
/* Define the physics-based easing as a reusable variable */
--spring-easing: linear(0, 0.016 0.5%, 0.06 1%, 0.226 2%, 1.116 5.4%, 1.375 6.6%, 1.527 7.7%, 1.565 8.2%, 1.585 8.8%, 1.581 9.3%, 1.559 9.8%, 1.458 10.9%, 0.937 14.3%, 0.784 15.5%, 0.693 16.6%, 0.67 17.1%, 0.657 17.7%, 0.671 18.7%, 0.729 19.8%, 1.042 23.3%, 1.13 24.5%, 1.182 25.6%, 1.201 26.7%, 1.192 27.7%, 1.156 28.8%, 0.977 32.2%, 0.925 33.4%, 0.894 34.5%, 0.882 35.6%, 0.887 36.6%, 0.907 37.7%, 1.045 42.4%, 1.069 44.5%, 1.059 46.3%, 0.979 50.9%, 0.96 53.4%, 0.966 55.3%, 1.013 59.9%, 1.024 62.3%, 0.986 71.2%, 1.008 79.9%, 0.995 88.9%, 1);
/* Apply the easing with a duration that fits the spring's complexity */
/* MANDATORY: Always include a duration; linear() does not calculate it automatically */
transition: scale 0.8s var(--spring-easing);
}
.spring:hover {
scale: 1.2;
}
Ví dụ: Hiệu ứng nảy
Ví dụ này cho thấy cách sử dụng hàm linear() tuỳ chỉnh để tạo hiệu ứng nảy.
.bounce {
/* Define the physics-based easing as a reusable variable */
--bounce-easing: linear(0, 0.214 14.7%, 0.386 23.7%, 0.598 31.9%, 0.999 44.7%, 0.807 52.6%, 0.762 56%, 0.747 59.4%, 0.758 62.4%, 0.793 65.6%, 0.999 77.4%, 0.961 81.2%, 0.949 84.8%, 0.956 88%, 0.993 95.5%, 1);
/* Apply the easing with a duration that fits the bounce's complexity */
/* MANDATORY: Always include a duration; linear() does not calculate it automatically */
transition: scale 0.4s var(--bounce-easing);
}
.bounce:hover {
scale: 1.2;
}
Những điểm chính cần xem xét
- Hiệu suất: Để có ảnh động dựa trên kiến thức vật lý mượt mà nhất, hãy áp dụng
linear()cho các thuộc tính chạy trên một luồng riêng biệt, chẳng hạn nhưtransformvàopacity. - Độ chính xác so với tải trọng: Mặc dù nhiều điểm dừng hơn sẽ giúp đường cong mượt mà hơn, nhưng cũng làm tăng kích thước của CSS. Hầu hết các trình tạo đều cho phép bạn "đơn giản hoá" đường cong để tìm ra sự cân bằng tối ưu giữa độ mượt và kích thước mã.
- Tránh sử dụng độ mờ cho hiệu ứng nảy: Việc áp dụng hiệu ứng nảy cho
opacitycó thể gây ra hiện tượng nhấp nháy gây khó chịu nếu giá trị vượt quá 0 hoặc 1. - Hỗ trợ tiếp cận: Ảnh động phức tạp dựa trên vật lý có thể gây mất tập trung hoặc gây nhạy cảm với chuyển động cho một số người dùng. Luôn tôn trọng lựa chọn ưu tiên của người dùng bằng cách giảm hoặc tắt các ảnh động này.
@media (prefers-reduced-motion: reduce) {
.element {
transition: none;
}
}
Chiến lược dự phòng
Dự phòng CSS
Đối với các trình duyệt không hỗ trợ linear(), hãy cung cấp một hàm easing chuẩn làm phương án dự phòng. Trình duyệt sẽ bỏ qua giá trị linear() nếu không nhận ra giá trị đó, quay lại khai báo hợp lệ trước đó.
.element {
/* Fallback for older browsers (standard smooth exit) */
transition: transform 0.8s ease-out;
/* Modern browsers will override with the physics-based easing */
transition-timing-function: linear(0, 1.1, 0.95, 1.02, 1);
}
Dự phòng thư viện JavaScript (Motion/GSAP)
Không bắt buộc: Nếu ảnh động vật lý có độ chân thực cao là yếu tố quan trọng ngay cả trong các trình duyệt cũ, hãy sử dụng thư viện JavaScript như Motion (motion.dev) hoặc GSAP (greensock.com) để xử lý ảnh động khi linear() không được hỗ trợ.
- Phát hiện tính năng hỗ trợ: Sử dụng
CSS.supports()để kiểm tra xem trình duyệt có xử lý hàmlinear()hay không. - Tải/áp dụng có điều kiện: Nếu không được hỗ trợ, hãy sử dụng phương thức triển khai hiệu ứng lò xo hoặc nảy của thư viện.
/* Detect if the browser supports the linear() function */
const supportsLinearEasing = window.CSS && CSS.supports('animation-timing-function', 'linear(0, 1)');
if (!supportsLinearEasing) {
/*
Example using Motion (motion.dev) for a spring fallback.
This should only be initialized if native CSS support is missing.
*/
import("https://cdn.jsdelivr.net/npm/motion@latest/dist/motion.js").then(({ animate, spring }) => {
animate(".element", { transform: "scale(1.2)" }, {
easing: spring({ stiffness: 100, damping: 10 })
});
});
}
Bạn cũng có thể sử dụng @supports trong CSS để phát hiện tính năng rõ ràng hơn:
@supports not (animation-timing-function: linear(0, 1)) {
.element {
/* Alternative experience for unsupported browsers */
transition-duration: 0.4s;
transition-timing-function: cubic-bezier(0.34, 1.56, 0.64, 1);
}
}