Move across the menu and the old underline retracts toward the new item while the new one grows from that side. Sibling selectors set transform-origin, a delayed transition holds it.
Also known as: sliding underline navbar, nav underline hover effect, underline follows mouse.
<nav class="hfx-nav-underline-follow"> <a href="#">Home</a> <a href="#" aria-current="page">Work</a> <a href="#">About</a> <a href="#">Contact</a> </nav>
.hfx-nav-underline-follow {
--c: var(--hfx-color, #3b82f6);
display: flex;
align-items: center;
font: 600 var(--hfx-size, 16px)/1.2 system-ui, sans-serif;
}
.hfx-nav-underline-follow a {
position: relative;
padding: 0.6em 0.9em;
color: inherit;
text-decoration: none;
transition: color 0.25s ease;
}
.hfx-nav-underline-follow a[aria-current="page"] { color: var(--c); }
.hfx-nav-underline-follow a::after {
content: "";
position: absolute;
left: 0.9em;
right: 0.9em;
bottom: 0.2em;
height: 0.14em;
border-radius: 1em;
background: var(--c);
transform: scaleX(0);
transform-origin: right;
transition: transform 0.3s cubic-bezier(0.65, 0, 0.35, 1);
}
.hfx-nav-underline-follow a:is(:hover, :focus-visible) ~ a::after { transform-origin: left; }
.hfx-nav-underline-follow a:is(:hover, :focus-visible) { color: var(--c); }
.hfx-nav-underline-follow a:is(:hover, :focus-visible)::after {
transform: scaleX(1);
transition: transform 0.3s cubic-bezier(0.65, 0, 0.35, 1), transform-origin 0s 0.3s;
}
@media (prefers-reduced-motion: reduce) {
.hfx-nav-underline-follow, .hfx-nav-underline-follow *, .hfx-nav-underline-follow::before, .hfx-nav-underline-follow::after, .hfx-nav-underline-follow *::before, .hfx-nav-underline-follow *::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.