Modern CSS Transitions
Polished hover and focus transitions for buttons, cards and links that work on any .btn or .card.
1Glassmorphism Hover
A frosted-glass card that turns clearer, brighter and lifts when hovered; place it over a colourful background. Class: fx-glassmorphism-hover
Maya Morgan
Backend Engineer
Frosted glass that clears on hover.
<div class="d-flex flex-wrap align-items-center justify-content-center gap-3 p-3 h-100 rounded-4" style="min-height:200px;background:radial-gradient(circle at 20% 25%, var(--wt-accent) 0 18%, transparent 19%),radial-gradient(circle at 82% 75%, var(--wt-secondary) 0 22%, transparent 23%),linear-gradient(135deg, var(--wt-primary), var(--wt-secondary))">
<div class="fx-glassmorphism-hover rounded-4 p-3" style="width:14rem">
<div class="d-flex align-items-center gap-2 mb-2">
<img src="../assets/img/avatar-6.svg" alt="Member avatar" class="rounded-circle" style="width:40px;height:40px">
<div>
<div class="fw-semibold small">
Maya Morgan
</div>
<div class="small opacity-75">
Backend Engineer
</div>
</div>
</div>
<p class="small mb-0">Frosted glass that clears on hover.</p>
</div>
</div>
/* CSS (already in assets/css/effects.css) */
.fx-glassmorphism-hover {
color: #fff; background: rgba(255, 255, 255, .14); border: 1px solid rgba(255, 255, 255, .28);
-webkit-backdrop-filter: blur(8px) saturate(140%); backdrop-filter: blur(8px) saturate(140%);
box-shadow: 0 8px 24px rgba(0, 0, 0, .12);
transition: background .45s, backdrop-filter .45s, transform .45s cubic-bezier(.2, .8, .2, 1), box-shadow .45s, border-color .45s;
}
.fx-glassmorphism-hover:hover, .fx-glassmorphism-hover:focus-within {
background: rgba(255, 255, 255, .24); border-color: rgba(255, 255, 255, .55);
-webkit-backdrop-filter: blur(16px) saturate(180%); backdrop-filter: blur(16px) saturate(180%);
transform: translateY(-5px); box-shadow: 0 18px 40px rgba(0, 0, 0, .2);
}
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
.fx-glassmorphism-hover { background: rgba(var(--wt-primary-rgb), .82); }
}
@media (prefers-reduced-motion: reduce) {
.fx-glassmorphism-hover, .fx-glassmorphism-hover::before, .fx-glassmorphism-hover::after, .fx-glassmorphism-hover *, .fx-glassmorphism-hover *::before, .fx-glassmorphism-hover *::after { animation: none !important; transition: none !important; }
}2Neon Fill Button
An outline button that fills with colour from the left and glows; works on any .btn or link. Class: fx-neon-fill-button
<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-lg fx-neon-fill-button">Get started</button>
<a href="#" class="btn fx-neon-fill-button rounded-pill">Learn more <i class="bi bi-arrow-right" aria-hidden="true"></i></a>
</div>
/* CSS (already in assets/css/effects.css) */
.fx-neon-fill-button, .btn.fx-neon-fill-button {
position: relative; isolation: isolate; overflow: hidden; z-index: 0;
color: var(--wt-primary-ink); background: transparent; border: 2px solid var(--wt-primary);
transition: color .35s ease, box-shadow .35s ease;
}
.fx-neon-fill-button::before {
content: ""; position: absolute; inset: 0; z-index: -1; background: var(--wt-primary);
transform: scaleX(0); transform-origin: left center; transition: transform .4s cubic-bezier(.7, 0, .3, 1);
}
.fx-neon-fill-button:hover, .fx-neon-fill-button:focus-visible, .btn.fx-neon-fill-button:hover, .btn.fx-neon-fill-button:focus-visible {
color: var(--wt-on-primary, #fff); border-color: var(--wt-primary);
box-shadow: 0 0 12px rgba(var(--wt-primary-rgb), .6), 0 0 32px rgba(var(--wt-primary-rgb), .35);
}
.fx-neon-fill-button:hover::before, .fx-neon-fill-button:focus-visible::before { transform: scaleX(1); }
@media (prefers-reduced-motion: reduce) {
.fx-neon-fill-button, .fx-neon-fill-button::before, .fx-neon-fill-button::after, .fx-neon-fill-button *, .fx-neon-fill-button *::before, .fx-neon-fill-button *::after { animation: none !important; transition: none !important; }
}3Liquid Ripple
A button that fills with a swirling liquid from the bottom on hover. Class: fx-liquid-ripple
<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-lg px-4 fx-liquid-ripple">Dive in</button>
<button type="button" class="btn rounded-pill fx-liquid-ripple">Hover me</button>
</div>
/* CSS (already in assets/css/effects.css) */
.fx-liquid-ripple, .btn.fx-liquid-ripple {
position: relative; isolation: isolate; overflow: hidden; z-index: 0;
color: var(--wt-primary-ink); background: var(--wt-surface, #fff); border: 2px solid var(--wt-primary);
transition: color .5s ease;
}
.fx-liquid-ripple::before {
content: ""; position: absolute; z-index: -1; left: 50%; top: 100%; width: 240%; aspect-ratio: 1;
margin-left: -120%; margin-top: 12%; border-radius: 42%;
background: var(--wt-primary);
transition: top .8s ease, margin-top .8s ease;
animation: fx-liquid-ripple-swirl 5s linear infinite;
}
.fx-liquid-ripple:hover, .fx-liquid-ripple:focus-visible, .btn.fx-liquid-ripple:hover, .btn.fx-liquid-ripple:focus-visible { color: var(--wt-on-primary, #fff); border-color: var(--wt-primary); }
.fx-liquid-ripple:hover::before, .fx-liquid-ripple:focus-visible::before { top: 50%; margin-top: -120%; }
.fx-liquid-ripple:active { transform: scale(.97); }
@keyframes fx-liquid-ripple-swirl { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
.fx-liquid-ripple, .fx-liquid-ripple::before, .fx-liquid-ripple::after, .fx-liquid-ripple *, .fx-liquid-ripple *::before, .fx-liquid-ripple *::after { animation: none !important; transition: none !important; }
}