Each letter rolls up and out while an accent copy rolls in underneath, one letter a beat after the last. The copy is a text-shadow one line below, so there is no duplicate markup.
Also known as: text roll hover, staggered text slide up, rolling letters.
<div class="hfx-text-letter-roll" aria-label="Portfolio"><span style="--i: 0">P</span><span style="--i: 1">o</span><span style="--i: 2">r</span><span style="--i: 3">t</span><span style="--i: 4">f</span><span style="--i: 5">o</span><span style="--i: 6">l</span><span style="--i: 7">i</span><span style="--i: 8">o</span></div>
.hfx-text-letter-roll {
--c: var(--hfx-color, #3b82f6);
font-size: calc(var(--hfx-size, 16px) * 2.5);
font-family: system-ui, sans-serif;
font-weight: 800;
line-height: 1.15;
cursor: default;
display: inline-flex;
overflow: hidden;
line-height: 1.2;}
.hfx-text-letter-roll span {
display: block;
text-shadow: 0 1.2em var(--c);
transition: transform 0.5s cubic-bezier(0.76, 0, 0.24, 1);
transition-delay: calc(var(--i) * 0.03s);
}
.hfx-text-letter-roll:hover span { transform: translateY(-1.2em); }
@media (prefers-reduced-motion: reduce) {
.hfx-text-letter-roll, .hfx-text-letter-roll *, .hfx-text-letter-roll::before, .hfx-text-letter-roll::after, .hfx-text-letter-roll *::before, .hfx-text-letter-roll *::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
}
}--hfx-color on the element or a parent.
Currently previewing #3b82f6.--hfx-size. Every other dimension is in
em, so the whole thing scales together. Currently previewing 16px.transition or animation
shorthand. Staggered delays are relative, so they keep their rhythm.