As funções de easing tradicionais do CSS, como ease-in ou cubic-bezier(), são limitadas a curvas simples, o que impossibilita a criação de efeitos complexos baseados em física, como saltos ou molas. A função de tempo linear() resolve isso permitindo que você forneça uma série de paradas que podem se aproximar de curvas complexas. As transições e animações são interpoladas com base em linhas retas entre as paradas, mas, com paradas suficientes, elas podem parecer suaves.
Etapas de implementação
- Gerar os pontos da curva:
traçar manualmente dezenas de pontos para uma mola ou um salto não é prático. Use uma função de tempo de uma biblioteca externa ou uma ferramenta para converter uma função de easing do JavaScript ou um caminho SVG na sintaxe
linear(). Opcional: armazene essas funções de tempo como propriedades personalizadas de CSS para reutilização em todo o site. - Defina a função de tempo:
aplique as paradas geradas à propriedade
transition-timing-functionouanimation-timing-functionou use as abreviaçõestransitionouanimation. - Ajuste a duração:
ao contrário dos mecanismos de física do JavaScript, em que a duração é derivada de propriedades físicas (massa, rigidez), o CSS ainda requer uma
durationfixa. Talvez seja necessário ajustar a duração para conseguir o efeito desejado.
Exemplo: Spring Easing
Este exemplo mostra como usar uma função linear() personalizada para criar um efeito de mola que ultrapassa o valor de destino antes de se estabilizar.
.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;
}
Exemplo: Bounce Easing
Este exemplo mostra como usar uma função linear() personalizada para criar um efeito de salto.
.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;
}
Principais Considerações
- Desempenho: para as animações baseadas em física mais suaves, aplique
linear()a propriedades executadas em uma linha de execução separada, comotransformeopacity. - Precisão x payload: embora mais paradas resultem em uma curva mais suave, elas também aumentam o tamanho do CSS. A maioria dos geradores permite "simplificar" a curva para encontrar o equilíbrio ideal entre suavidade e tamanho do código.
- Evite a opacidade para saltos: aplicar suavizações de salto a
opacitypode causar uma oscilação visualmente desagradável se o valor ultrapassar 0 ou 1. - Acessibilidade: animações complexas baseadas em física podem distrair ou causar sensibilidade ao movimento em alguns usuários. Sempre respeite as preferências do usuário reduzindo ou desativando essas animações.
@media (prefers-reduced-motion: reduce) {
.element {
transition: none;
}
}
Estratégias de fallback
CSS substituto
Para navegadores que não oferecem suporte a linear(), forneça uma função de easing padrão como substituta. O navegador vai ignorar o valor linear() se não o reconhecer, voltando para a declaração válida anterior.
.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 da biblioteca JavaScript (Motion/GSAP)
Opcional: se uma animação física de alta fidelidade for essencial mesmo em navegadores mais antigos, use uma biblioteca JavaScript como Motion (motion.dev) ou GSAP (greensock.com) para processar a animação quando linear() não for compatível.
- Detectar suporte: use
CSS.supports()para verificar se o navegador processa a funçãolinear(). - Carregar/aplicar condicionalmente: se não houver suporte, use a implementação de mola ou de retorno da biblioteca.
/* 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 })
});
});
}
Você também pode usar @supports em CSS para uma detecção de recursos mais explícita:
@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);
}
}