Modern CSS Animations
Keyframe animations for cards, icons, loaders and headings - drop a class on an element and it comes alive.
1Gradient Wave
A banner whose theme gradient flows sideways while a soft wave rolls along its bottom edge. Class: fx-gradient-wave
<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-gradient-wave rounded-4 p-4 w-100" style="max-width:19rem">
<p class="small text-uppercase fw-semibold mb-1 opacity-75">New season</p>
<h3 class="h4 fw-bold mb-3">Smart property search, real advice</h3>
<a href="#" class="btn btn-light btn-sm">Explore</a>
</div>
</div>
/* CSS (already in assets/css/effects.css) */
.fx-gradient-wave {
position: relative; overflow: hidden; color: var(--wt-on-primary, #fff);
background: linear-gradient(90deg, var(--wt-primary), var(--wt-secondary), var(--wt-accent), var(--wt-primary));
background-size: 200% 100%;
animation: fx-gradient-wave-flow 8s linear infinite;
}
.fx-gradient-wave::after {
content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 24px; pointer-events: none;
background: radial-gradient(20px 12px at 50% 100%, rgba(255, 255, 255, .35) 98%, transparent 100%) 0 100% / 40px 24px repeat-x;
animation: fx-gradient-wave-roll 2.4s linear infinite;
}
.fx-gradient-wave > * { position: relative; z-index: 1; }
@keyframes fx-gradient-wave-flow { to { background-position: -200% 0; } }
@keyframes fx-gradient-wave-roll { to { background-position: 40px 100%; } }
@media (prefers-reduced-motion: reduce) {
.fx-gradient-wave, .fx-gradient-wave::before, .fx-gradient-wave::after, .fx-gradient-wave *, .fx-gradient-wave *::before, .fx-gradient-wave *::after { animation: none !important; transition: none !important; }
}2Glitch Text
Splits a heading into offset colour slices that jitter like a broken screen; repeat the text in data-text. Class: fx-glitch-text
GLITCH MODE
<div class="d-flex flex-wrap align-items-center justify-content-center gap-3 p-3 h-100" style="min-height:200px">
<div class="bg-dark rounded-4 px-4 py-5 text-center w-100" style="max-width:19rem">
<h2 class="display-6 fw-bold text-white mb-0 fx-glitch-text" data-text="GLITCH MODE">GLITCH MODE</h2>
</div>
</div>
/* CSS (already in assets/css/effects.css) */
.fx-glitch-text { position: relative; display: inline-block; }
.fx-glitch-text::before, .fx-glitch-text::after {
content: attr(data-text); position: absolute; inset: 0; pointer-events: none;
-webkit-clip-path: inset(50% 0 50% 0); clip-path: inset(50% 0 50% 0);
}
.fx-glitch-text::before { color: var(--wt-accent); left: 2px; text-shadow: -1px 0 var(--wt-primary); animation: fx-glitch-text-a 2.6s steps(1) infinite; }
.fx-glitch-text::after { color: var(--wt-secondary); left: -2px; text-shadow: 1px 0 var(--wt-accent); animation: fx-glitch-text-b 3.1s steps(1) infinite; }
@keyframes fx-glitch-text-a {
0% { -webkit-clip-path: inset(0 0 82% 0); clip-path: inset(0 0 82% 0); transform: translate(-3px, -1px); }
15% { -webkit-clip-path: inset(30% 0 52% 0); clip-path: inset(30% 0 52% 0); transform: translate(3px, 1px); }
30% { -webkit-clip-path: inset(62% 0 20% 0); clip-path: inset(62% 0 20% 0); transform: translate(-2px, 0); }
45% { -webkit-clip-path: inset(50% 0 50% 0); clip-path: inset(50% 0 50% 0); }
80% { -webkit-clip-path: inset(12% 0 70% 0); clip-path: inset(12% 0 70% 0); transform: translate(2px, -1px); }
90% { -webkit-clip-path: inset(50% 0 50% 0); clip-path: inset(50% 0 50% 0); }
}
@keyframes fx-glitch-text-b {
0% { -webkit-clip-path: inset(70% 0 8% 0); clip-path: inset(70% 0 8% 0); transform: translate(2px, 1px); }
20% { -webkit-clip-path: inset(8% 0 76% 0); clip-path: inset(8% 0 76% 0); transform: translate(-3px, 0); }
35% { -webkit-clip-path: inset(50% 0 50% 0); clip-path: inset(50% 0 50% 0); }
70% { -webkit-clip-path: inset(40% 0 38% 0); clip-path: inset(40% 0 38% 0); transform: translate(3px, -1px); }
85% { -webkit-clip-path: inset(50% 0 50% 0); clip-path: inset(50% 0 50% 0); }
}
@media (prefers-reduced-motion: reduce) {
.fx-glitch-text, .fx-glitch-text::before, .fx-glitch-text::after, .fx-glitch-text *, .fx-glitch-text *::before, .fx-glitch-text *::after { animation: none !important; transition: none !important; }
}