Modern CSS Animations
Keyframe animations for cards, icons, loaders and headings - drop a class on an element and it comes alive.
1Pulse Wave Effect
Sends expanding rings out of a button, avatar or status dot to draw the eye. Class: fx-pulse-wave-effect
Mason Silva
Live now<div class="d-flex flex-wrap align-items-center justify-content-center gap-3 p-3 h-100" style="min-height:200px">
<button type="button" class="btn btn-primary rounded-circle d-inline-flex align-items-center justify-content-center fs-4 fx-pulse-wave-effect" style="width:4rem;height:4rem" aria-label="Start live session"><i class="bi bi-broadcast" aria-hidden="true"></i></button>
<div class="d-flex align-items-center gap-2">
<img src="../assets/img/avatar-2.svg" alt="Portrait of the host" class="rounded-circle fx-pulse-wave-effect" width="48" height="48">
<div>
<div class="fw-semibold small">
Mason Silva
</div>
<span class="badge text-bg-success">Live now</span>
</div>
</div>
</div>
/* CSS (already in assets/css/effects.css) */
.fx-pulse-wave-effect { animation: fx-pulse-wave-effect-pulse 2s ease-out infinite; }
@keyframes fx-pulse-wave-effect-pulse {
0% { box-shadow: 0 0 0 0 rgba(var(--wt-primary-rgb), .55), 0 0 0 0 rgba(var(--wt-primary-rgb), .35); }
70% { box-shadow: 0 0 0 16px rgba(var(--wt-primary-rgb), 0), 0 0 0 32px rgba(var(--wt-primary-rgb), 0); }
100% { box-shadow: 0 0 0 0 rgba(var(--wt-primary-rgb), 0), 0 0 0 0 rgba(var(--wt-primary-rgb), 0); }
}
@media (prefers-reduced-motion: reduce) {
.fx-pulse-wave-effect, .fx-pulse-wave-effect::before, .fx-pulse-wave-effect::after, .fx-pulse-wave-effect *, .fx-pulse-wave-effect *::before, .fx-pulse-wave-effect *::after { animation: none !important; transition: none !important; }
}2Particle Float
Fills a card or panel with small glowing particles that rise behind its content. Class: fx-particle-float
Where every dinner feels like a celebration
Particles drift up behind the content.
<div class="d-flex flex-wrap align-items-center justify-content-center gap-3 p-3 h-100" style="min-height:200px">
<div class="fx-particle-float rounded-4 border p-4 text-center w-100" style="max-width:18rem">
<div class="fs-2 text-primary">
<i class="bi bi-stars" aria-hidden="true"></i>
</div>
<h3 class="h5 mb-1">Where every dinner feels like a celebration</h3>
<p class="small text-body-secondary mb-0">Particles drift up behind the content.</p>
</div>
</div>
/* CSS (already in assets/css/effects.css) */
.fx-particle-float { position: relative; isolation: isolate; overflow: hidden; }
.fx-particle-float::before, .fx-particle-float::after {
content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none;
background-image:
radial-gradient(circle at 12% 30%, rgba(var(--wt-primary-rgb), .7) 0 2px, transparent 3px),
radial-gradient(circle at 38% 80%, rgba(var(--wt-accent-rgb), .7) 0 3px, transparent 4px),
radial-gradient(circle at 62% 45%, rgba(var(--wt-secondary-rgb), .6) 0 2px, transparent 3px),
radial-gradient(circle at 86% 15%, rgba(var(--wt-primary-rgb), .6) 0 3px, transparent 4px);
background-size: 160px 160px;
animation: fx-particle-float-rise 10s linear infinite;
}
.fx-particle-float::after { background-size: 230px 230px; opacity: .6; animation: fx-particle-float-rise-slow 16s linear infinite; }
@keyframes fx-particle-float-rise { to { background-position: 0 -160px; } }
@keyframes fx-particle-float-rise-slow { to { background-position: 0 -230px; } }
@media (prefers-reduced-motion: reduce) {
.fx-particle-float, .fx-particle-float::before, .fx-particle-float::after, .fx-particle-float *, .fx-particle-float *::before, .fx-particle-float *::after { animation: none !important; transition: none !important; }
}3Orbital Motion
Two small planets circle around an avatar, logo or icon on separate orbits. Class: fx-orbital-motion
<div class="d-flex flex-wrap align-items-center justify-content-center gap-3 p-3 h-100" style="min-height:200px">
<div class="fx-orbital-motion">
<img src="../assets/img/avatar-5.svg" alt="Team member avatar" class="rounded-circle shadow" style="width:4.5rem;height:4.5rem">
</div>
</div>
/* CSS (already in assets/css/effects.css) */
.fx-orbital-motion {
position: relative; display: inline-grid; place-items: center; width: 9rem; height: 9rem;
border-radius: 50%; border: 1px dashed rgba(var(--wt-primary-rgb), .45);
}
.fx-orbital-motion::before, .fx-orbital-motion::after {
content: ""; position: absolute; top: 50%; left: 50%; border-radius: 50%; pointer-events: none;
}
.fx-orbital-motion::before {
width: 14px; height: 14px; margin: -7px; background: var(--wt-primary);
box-shadow: 0 0 10px rgba(var(--wt-primary-rgb), .7);
animation: fx-orbital-motion-outer 5s linear infinite;
}
.fx-orbital-motion::after {
width: 10px; height: 10px; margin: -5px; background: var(--wt-accent);
animation: fx-orbital-motion-inner 3.2s linear infinite reverse;
}
@keyframes fx-orbital-motion-outer { from { transform: rotate(0deg) translateX(4.5rem) rotate(0deg); } to { transform: rotate(360deg) translateX(4.5rem) rotate(-360deg); } }
@keyframes fx-orbital-motion-inner { from { transform: rotate(0deg) translateX(3.1rem); } to { transform: rotate(360deg) translateX(3.1rem); } }
@media (prefers-reduced-motion: reduce) {
.fx-orbital-motion, .fx-orbital-motion::before, .fx-orbital-motion::after, .fx-orbital-motion *, .fx-orbital-motion *::before, .fx-orbital-motion *::after { animation: none !important; transition: none !important; }
}