Modern CSS Transitions
Polished hover and focus transitions for buttons, cards and links that work on any .btn or .card.
13D Flip Card
Flips a card over in 3D on hover or focus to show its back; use the -inner, -front and -back child classes. Class: fx-3d-flip-card
<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-3d-flip-card" style="width:13rem;height:11rem" tabindex="0">
<div class="fx-3d-flip-card-inner">
<div class="fx-3d-flip-card-front shadow">
<img src="https://images.unsplash.com/photo-1753162658407-93888aaabfae?auto=format&fit=crop&w=1200&h=800&q=70" alt="Portrait of Zoe Tanaka" class="w-100 h-100 object-fit-cover">
</div>
<div class="fx-3d-flip-card-back text-center">
<div class="fw-bold">
Zoe Tanaka
</div>
<div class="small opacity-75 mb-2">
Art Director
</div>
<a href="#" class="btn btn-light btn-sm">View profile</a>
</div>
</div>
</div>
</div>
/* CSS (already in assets/css/effects.css) */
.fx-3d-flip-card { perspective: 1000px; }
.fx-3d-flip-card .fx-3d-flip-card-inner {
position: relative; width: 100%; height: 100%; transform-style: preserve-3d;
transition: transform .7s cubic-bezier(.4, .2, .2, 1);
}
.fx-3d-flip-card:hover .fx-3d-flip-card-inner, .fx-3d-flip-card:focus-within .fx-3d-flip-card-inner { transform: rotateY(180deg); }
.fx-3d-flip-card .fx-3d-flip-card-front, .fx-3d-flip-card .fx-3d-flip-card-back {
position: absolute; inset: 0; -webkit-backface-visibility: hidden; backface-visibility: hidden;
border-radius: var(--wt-radius-lg, 1rem); overflow: hidden;
}
.fx-3d-flip-card .fx-3d-flip-card-back {
transform: rotateY(180deg); display: flex; flex-direction: column; justify-content: center; padding: 1rem;
color: var(--wt-on-primary, #fff); background: linear-gradient(135deg, var(--wt-primary), var(--wt-secondary));
}
@media (prefers-reduced-motion: reduce) {
.fx-3d-flip-card, .fx-3d-flip-card::before, .fx-3d-flip-card::after, .fx-3d-flip-card *, .fx-3d-flip-card *::before, .fx-3d-flip-card *::after { animation: none !important; transition: none !important; }
}2Split Text Fill
Fills a heading or link with the primary colour from both sides at once on hover - top half from the left, bottom half from the right. Class: fx-split-text-fill
<div class="d-flex flex-wrap align-items-center justify-content-center gap-3 p-3 h-100" style="min-height:200px">
<a href="#" class="display-6 fw-bold fx-split-text-fill">Split and fill</a>
</div>
/* CSS (already in assets/css/effects.css) */
.fx-split-text-fill {
display: inline-block; text-decoration: none;
-webkit-text-fill-color: transparent;
background-image: linear-gradient(var(--wt-primary), var(--wt-primary)), linear-gradient(var(--wt-primary), var(--wt-primary)), linear-gradient(currentColor, currentColor);
background-repeat: no-repeat;
background-position: 0 0, 100% 100%, 0 0;
background-size: 0% 50%, 0% 50%, 100% 100%;
-webkit-background-clip: text; background-clip: text;
transition: background-size .6s cubic-bezier(.7, 0, .3, 1);
}
.fx-split-text-fill:hover, .fx-split-text-fill:focus-visible { background-size: 100% 50%, 100% 50%, 100% 100%; }
@supports not ((background-clip: text) or (-webkit-background-clip: text)) {
.fx-split-text-fill { -webkit-text-fill-color: currentColor; background: none; }
.fx-split-text-fill:hover { color: var(--wt-primary-ink); }
}
@media (prefers-reduced-motion: reduce) {
.fx-split-text-fill, .fx-split-text-fill::before, .fx-split-text-fill::after, .fx-split-text-fill *, .fx-split-text-fill *::before, .fx-split-text-fill *::after { animation: none !important; transition: none !important; }
}