Smooth Hover Underlines in Webflow (Box-Shadow)

Beginner 12:43 webflowcsshoverbox-shadowanimation

Build smooth, growing hover underline effects in Webflow with box-shadow and CSS transitions — from bottom, top, left, right, to full-height fills, no code.

Key takeaways

  • Animate underlines with an inset box-shadow, not a real border — a border changes the element's box and shoves your layout; a shadow doesn't.
  • The whole effect is one transition on box-shadow (≈600ms, ease-out cubic): start with a zero-size inset shadow and reveal it on hover by changing an offset.
  • Direction is just which offset you move on hover: negative Y grows from the bottom, positive Y from the top, positive X from the left, negative X from the right.
  • For left/right underlines, add matching padding first so there's room for the line to appear.
  • For a full-height fill, the hover Y offset = font-size × unitless line-height (e.g. 7vw × 1.5 = 10.5vw); if line-height has a unit, use it directly.
  • Set the link color to inherit and remove the default underline so it isn't stuck link-blue — and on a full-height fill, switch the text to a contrasting color so it doesn't vanish into the shadow.

Video chapters

  1. 00:00 Intro
  2. 01:56 Example 1: line growing from the bottom
  3. 04:57 Example 2: line growing from the top
  4. 05:48 Example 3: line growing from the left
  5. 06:31 Example 4: line growing from the right
  6. 07:27 Example 5: full-height line from the bottom
  7. 09:55 Example 6: full-height line from the top
  8. 10:31 Bonus: multi-line growing effects
  9. 11:56 Outro

By the end of this lesson you’ll be able to build smooth, growing hover underlines in Webflow — the elegant kind that slide in from the bottom, top, left, or right, or fill the whole height of the text — all with box-shadow and a couple of transitions, and zero custom code.

The trick behind every variation is the same: don’t use a real border. A border adds to the element’s box, so animating it shoves everything around it. A box-shadow, by contrast, is painted outside the layout box — it can grow and shrink without disturbing a single neighbor. Learn the one base setup and the other six effects are just a tweaked offset.

I demo it on links because they’re the natural fit, but the exact same logic works on a link block, a container, a section — any element you like.

How it works

The base effect — a line growing from the bottom — is built in three moves. First, style the link: set its color to inherit (so it isn’t stuck the default link-blue) and remove the default underline with text-decoration: none. Second, add an inset box-shadow with every value (X, Y, blur, size) at zero and the color set to whatever you want the underline to be. Third, transition the box-shadow — a fairly long 600ms with ease-out cubic is what makes it feel smooth (you can transition color the same way). Then in the hover state, nudge the shadow’s Y offset to a small negative value like -1vw. That’s the whole effect: the invisible zero-size shadow grows into a crisp underline sliding up from the bottom.

Once that clicks, direction is just an offset. Flip the hover Y to positive 1vw and the line grows from the top instead. Move the value to the X axis — positive 1vw grows it from the left, negative 1vw from the right. The only extra step for the horizontal versions is adding a bit of matching padding (left or right) so there’s actually room for the line to appear beside the text.

The full-height fill looks fancier but uses the same Y offset — the only question is how tall to make it. You can’t use a percentage here, so the value comes from the font: multiply the font-size by a unitless line-height. With font-size: 7vw and line-height: 1.5, that’s 7 × 1.5 = 10.5vw, so the hover Y offset is -10.5vw (positive for a top fill). If your line-height already has a unit (px, em…), just use that value directly. Two finishing touches: add horizontal padding so the fill has breathing room, and switch the text color to something contrasting (like white) on hover — otherwise the text disappears into the shadow.

Finally, the multi-line bonus is just the base idea applied twice. Add two inset shadows in the normal state, then on hover give them opposite offsets — one 1vw, one -1vw — to animate top and bottom together. Move those to the X axis for left and right. Same mechanism, more sides. Every one of these effects is pure box-shadow and transitions — no custom code anywhere.

How to use it

  1. Style the link — set color: inherit and text-decoration: none so it takes the body color and loses the default underline.
  2. Add the base shadow — an inset box-shadow with X, Y, blur, and size all at 0 and the color set to your accent (e.g. Webflow blue).
  3. Add the transition — transition box-shadow at ~600ms, ease-out cubic (optionally color too, same values).
  4. Set the hover — in the hover state, change the box-shadow’s Y offset to -1vw for a bottom underline. That’s the classic effect done.
  5. Change direction — flip Y to +1vw for top, or move the value to the X offset (+1vw left, -1vw right); for left/right, add matching padding so the line has room.
  6. Make it full-height — set the hover Y offset to font-size × line-height (e.g. 10.5vw for 7vw × 1.5), add horizontal padding, and switch the text color to a contrasting one on hover.
  7. Animate multiple sides — add two inset shadows in the normal state and give them opposite offsets on hover (top + bottom, or left + right).

That’s a whole collection of hover underlines from one idea: an inset shadow you reveal with a transition. Master the base setup and every variation is a two-second tweak.

Resources

Frequently asked questions

How do I add an animated underline in Webflow without shifting the layout?
Use an inset box-shadow instead of a border. Add an inset shadow with all offsets at zero, transition the box-shadow (around 600ms, ease-out cubic), and on hover give it a small offset so the colored line slides in. Because a shadow doesn't take up space, nothing around the link moves.
Why use box-shadow instead of border-bottom for hover underlines?
A real border adds to the element's height, so animating it pushes surrounding content around. A box-shadow is painted outside the layout box, so it can grow and shrink smoothly without disturbing anything else.
How do I control which direction the underline grows from?
It's just the offset you animate on hover. A negative Y grows the line from the bottom, a positive Y from the top, a positive X from the left, and a negative X from the right. For left and right, add a bit of matching padding so there's room for it.
How do I make the hover line fill the full height of the text?
Set the hover box-shadow's Y offset to font-size × line-height. If your line-height is unitless (e.g. 1.5), multiply it by the font size and keep the same unit — 7vw × 1.5 = 10.5vw. If line-height already has a unit, use that value directly. Also switch the text to a contrasting color so it stays readable over the fill.
Can I animate more than one underline at once?
Yes — add two inset shadows in the normal state and give them opposite offsets on hover (one at 1vw, one at -1vw) to animate top and bottom together, or move those values to the X axis for left and right. Same mechanism, more sides.

← Back to the course

Also part of these courses