Le funzioni di easing CSS tradizionali come ease-in o cubic-bezier() sono limitate a curve semplici, il che rende impossibile creare effetti complessi basati sulla fisica come rimbalzi o molle. La funzione di timing linear() risolve questo problema consentendoti di fornire una serie di punti di interruzione che possono approssimare curve complesse. Le transizioni e le animazioni vengono interpolate in base a linee rette tra le fermate, ma con un numero sufficiente di fermate possono apparire fluide.
Procedura di implementazione
- Genera i punti di arresto della curva:
tracciare manualmente decine di punti per un effetto molla o rimbalzo non è pratico. Utilizza una funzione di timing da una libreria esterna o uno strumento per convertire una funzione di easing JavaScript esistente o un percorso SVG nella sintassi
linear(). (Facoltativo) Memorizza queste funzioni di timing come proprietà personalizzate CSS per riutilizzarle in tutto il sito. - Definisci la funzione di timing:
applica i punti di interruzione generati alla proprietà
transition-timing-functionoanimation-timing-functionoppure tramite le abbreviazionitransitionoanimation. - Regola la durata:
a differenza dei motori fisici JavaScript in cui la durata è derivata da proprietà fisiche (massa, rigidità), CSS richiede comunque un valore
durationfisso. Potresti dover regolare la durata per ottenere l'effetto desiderato.
Esempio: Spring Easing
Questo esempio mostra come utilizzare una funzione linear() personalizzata per creare un effetto molla che supera il valore target prima di stabilizzarsi.
.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;
}
Esempio: Esempio: Rimbalzo
Questo esempio mostra come utilizzare una funzione linear() personalizzata per creare un effetto di rimbalzo.
.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;
}
Considerazioni principali
- Prestazioni: per ottenere animazioni basate sulla fisica più fluide, applica
linear()alle proprietà eseguite su un thread separato, ad esempiotransformeopacity. - Precisione e payload: un numero maggiore di punti di interruzione genera una curva più uniforme, ma aumenta anche le dimensioni del CSS. La maggior parte dei generatori consente di "semplificare" la curva per trovare l'equilibrio ottimale tra fluidità e dimensioni del codice.
- Evita l'opacità per i rimbalzi: l'applicazione di easing di rimbalzo a
opacitypuò causare sfarfallii visivamente fastidiosi se il valore supera 0 o 1. - Accessibilità: le animazioni complesse basate sulla fisica possono distrarre o causare sensibilità al movimento per alcuni utenti. Rispetta sempre le preferenze dell'utente riducendo o disattivando queste animazioni.
@media (prefers-reduced-motion: reduce) {
.element {
transition: none;
}
}
Strategie di riserva
CSS di fallback
Per i browser che non supportano linear(), fornisci una funzione di easing standard come opzione di riserva. Il browser ignorerà il valore linear() se non lo riconosce, tornando alla dichiarazione valida precedente.
.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);
}
Fallback della libreria JavaScript (Motion/GSAP)
(Facoltativo) Se un'animazione fisica ad alta fedeltà è fondamentale anche nei browser meno recenti, utilizza una libreria JavaScript come Motion (motion.dev) o GSAP (greensock.com) per gestire l'animazione quando linear() non è supportato.
- Rileva il supporto: utilizza
CSS.supports()per verificare se il browser gestisce la funzionelinear(). - Carica/applica in modo condizionale: se non è supportata, utilizza l'implementazione di rimbalzo o molla della libreria.
/* 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 })
});
});
}
Puoi anche utilizzare @supports in CSS per un rilevamento più esplicito delle funzionalità:
@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);
}
}