One pill slides between the items of a dark floating navbar to whichever you hover, then glides back to the current page. Pure CSS with :has() and equal-width grid columns.
Also known as: sliding indicator navbar, nav pill hover animation, animated nav highlight.
<nav class="hfx-nav-sliding-pill"> <a href="#" aria-current="page">Home</a> <a href="#">Work</a> <a href="#">About</a> <a href="#">Contact</a> </nav>
.hfx-nav-sliding-pill {
--c: var(--hfx-color, #3b82f6);
--pos: 0;
position: relative;
isolation: isolate;
display: inline-grid;
grid-auto-flow: column;
grid-auto-columns: 1fr;
padding: 0.3em;
border: 1px solid color-mix(in srgb, var(--c) 30%, transparent);
border-radius: 2em;
background: color-mix(in srgb, var(--c) 12%, #111827);
font: 600 var(--hfx-size, 16px)/1.2 system-ui, sans-serif;
}
.hfx-nav-sliding-pill::before {
content: "";
position: absolute;
z-index: -1;
top: 0.3em;
bottom: 0.3em;
left: 0.3em;
width: calc((100% - 0.6em) / 4);
border-radius: 2em;
background: var(--c);
box-shadow: 0 0.3em 0.9em -0.2em color-mix(in srgb, var(--c) 70%, transparent);
transform: translateX(calc(var(--pos) * 100%));
transition: transform 0.45s cubic-bezier(0.34, 1.3, 0.64, 1);
}
.hfx-nav-sliding-pill a {
padding: 0.6em 1.1em;
border-radius: 2em;
color: rgb(255 255 255 / 0.6);
text-align: center;
text-decoration: none;
transition: color 0.3s ease;
}
.hfx-nav-sliding-pill a[aria-current="page"],
.hfx-nav-sliding-pill a:is(:hover, :focus-visible) { color: #fff; }
.hfx-nav-sliding-pill:has(a:is(:hover, :focus-visible)) a[aria-current="page"]:not(:hover, :focus-visible) { color: rgb(255 255 255 / 0.6); }
.hfx-nav-sliding-pill:has(a:nth-child(1):is(:hover, :focus-visible)) { --pos: 0; }
.hfx-nav-sliding-pill:has(a:nth-child(2):is(:hover, :focus-visible)) { --pos: 1; }
.hfx-nav-sliding-pill:has(a:nth-child(3):is(:hover, :focus-visible)) { --pos: 2; }
.hfx-nav-sliding-pill:has(a:nth-child(4):is(:hover, :focus-visible)) { --pos: 3; }
@media (prefers-reduced-motion: reduce) {
.hfx-nav-sliding-pill, .hfx-nav-sliding-pill *, .hfx-nav-sliding-pill::before, .hfx-nav-sliding-pill::after, .hfx-nav-sliding-pill *::before, .hfx-nav-sliding-pill *::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.