Pre-defined CSS cubic-bezier timing functions for consistent animations based on easing equations, organized by animation type (ease-in, ease-out, ease-in-out).
Timing functions that start slow and accelerate, ideal for elements entering the viewport or beginning animations.
$ease-in-quad: cubic-bezier(0.550, 0.085, 0.680, 0.530);
$ease-in-cubic: cubic-bezier(0.550, 0.055, 0.675, 0.190);
$ease-in-quart: cubic-bezier(0.895, 0.030, 0.685, 0.220);
$ease-in-quint: cubic-bezier(0.755, 0.050, 0.855, 0.060);
$ease-in-sine: cubic-bezier(0.470, 0.000, 0.745, 0.715);
$ease-in-expo: cubic-bezier(0.950, 0.050, 0.795, 0.035);
$ease-in-circ: cubic-bezier(0.600, 0.040, 0.980, 0.335);
$ease-in-back: cubic-bezier(0.600, -0.280, 0.735, 0.045);Timing functions that start fast and decelerate, ideal for elements leaving the viewport or ending animations.
$ease-out-quad: cubic-bezier(0.250, 0.460, 0.450, 0.940);
$ease-out-cubic: cubic-bezier(0.215, 0.610, 0.355, 1.000);
$ease-out-quart: cubic-bezier(0.165, 0.840, 0.440, 1.000);
$ease-out-quint: cubic-bezier(0.230, 1.000, 0.320, 1.000);
$ease-out-sine: cubic-bezier(0.390, 0.575, 0.565, 1.000);
$ease-out-expo: cubic-bezier(0.190, 1.000, 0.220, 1.000);
$ease-out-circ: cubic-bezier(0.075, 0.820, 0.165, 1.000);
$ease-out-back: cubic-bezier(0.175, 0.885, 0.320, 1.275);Timing functions that start slow, accelerate in the middle, then decelerate, ideal for smooth bidirectional animations.
$ease-in-out-quad: cubic-bezier(0.455, 0.030, 0.515, 0.955);
$ease-in-out-cubic: cubic-bezier(0.645, 0.045, 0.355, 1.000);
$ease-in-out-quart: cubic-bezier(0.770, 0.000, 0.175, 1.000);
$ease-in-out-quint: cubic-bezier(0.860, 0.000, 0.070, 1.000);
$ease-in-out-sine: cubic-bezier(0.445, 0.050, 0.550, 0.950);
$ease-in-out-expo: cubic-bezier(1.000, 0.000, 0.000, 1.000);
$ease-in-out-circ: cubic-bezier(0.785, 0.135, 0.150, 0.860);
$ease-in-out-back: cubic-bezier(0.680, -0.550, 0.265, 1.550);.fade-in {
opacity: 0;
transition: opacity 0.3s $ease-out-cubic;
&.visible {
opacity: 1;
}
}
.slide-up {
transform: translateY(20px);
transition: transform 0.4s $ease-out-quart;
&.animated {
transform: translateY(0);
}
}
.bounce-button {
transition: transform 0.2s $ease-out-back;
&:hover {
transform: scale(1.05);
}
&:active {
transform: scale(0.95);
transition-timing-function: $ease-in-back;
}
}.modal {
opacity: 0;
transform: scale(0.8);
transition:
opacity 0.3s $ease-out-cubic,
transform 0.3s $ease-out-back;
&.open {
opacity: 1;
transform: scale(1);
}
&.closing {
transition-timing-function: $ease-in-cubic, $ease-in-back;
}
}
.modal-backdrop {
opacity: 0;
transition: opacity 0.2s $ease-out-quad;
&.visible {
opacity: 1;
}
}.nav-item {
position: relative;
&::after {
content: '';
position: absolute;
bottom: 0;
left: 0;
width: 0;
height: 2px;
background-color: currentColor;
transition: width 0.3s $ease-out-expo;
}
&:hover::after {
width: 100%;
}
}
.mobile-menu {
transform: translateX(-100%);
transition: transform 0.4s $ease-out-circ;
&.open {
transform: translateX(0);
}
}@keyframes spin {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
@keyframes pulse {
0%, 100% { transform: scale(1); }
50% { transform: scale(1.1); }
}
.loading-spinner {
animation: spin 1s $ease-in-out-cubic infinite;
}
.pulse-loader {
animation: pulse 1.5s $ease-in-out-sine infinite;
}
.bouncing-dots {
.dot {
animation: bounce 1.4s $ease-in-out-back infinite;
&:nth-child(1) { animation-delay: 0.0s; }
&:nth-child(2) { animation-delay: 0.2s; }
&:nth-child(3) { animation-delay: 0.4s; }
}
}
@keyframes bounce {
0%, 80%, 100% { transform: scale(0); }
40% { transform: scale(1); }
}.card {
transition:
transform 0.3s $ease-out-quart,
box-shadow 0.3s $ease-out-quad;
&:hover {
transform: translateY(-4px);
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15);
}
}
.flip-card {
.card-inner {
transition: transform 0.6s $ease-in-out-back;
transform-style: preserve-3d;
}
&:hover .card-inner {
transform: rotateY(180deg);
}
}.floating-label {
.label {
transition: all 0.2s $ease-out-cubic;
transform-origin: left top;
}
.input:focus + .label,
.input:not(:placeholder-shown) + .label {
transform: translateY(-20px) scale(0.8);
}
}
.input-underline {
position: relative;
&::after {
content: '';
position: absolute;
bottom: 0;
left: 50%;
width: 0;
height: 2px;
background-color: #3498db;
transition:
width 0.3s $ease-out-expo,
left 0.3s $ease-out-expo;
}
&:focus::after {
width: 100%;
left: 0;
}
}.gpu-accelerated {
// Trigger hardware acceleration
transform: translateZ(0);
will-change: transform, opacity;
// Use transform instead of changing layout properties
transition: transform 0.3s $ease-out-cubic;
&:hover {
transform: translateY(-2px) translateZ(0);
}
}.animated-element {
transition: transform 0.3s $ease-out-cubic;
@media (prefers-reduced-motion: reduce) {
transition: none;
}
}
// Alternative: Use simpler animations for reduced motion
@media (prefers-reduced-motion: reduce) {
.complex-animation {
transition: opacity 0.2s ease;
}
}
@media (prefers-reduced-motion: no-preference) {
.complex-animation {
transition:
transform 0.4s $ease-out-back,
opacity 0.3s $ease-out-cubic,
box-shadow 0.3s $ease-out-quad;
}
}