Great hover buttons aren’t about complexity — they’re about clarity, intention, and choosing the right tool at the right time. This lesson breaks down five hover micro-interactions, from a bouncy expanding button to a light-and-shadow 3D effect, and along the way answers the question that actually matters: when should this be GSAP, when is CSS enough, and how do the two work together?
There’s a structural pattern behind all of them, and a mindset behind the tool choice. Get both, and you’ll build hover effects that feel polished without over-engineering them.
How it works
The structure. Every button here is a link block, not Webflow’s native button element — because a link block can nest children (an icon, an overlay div, a text wrapper), and these effects animate those children. A few reusable moves show up again and again: an overflow: hidden wrapper to mask a moving element; SVG icons with fill: currentColor so they inherit the button’s color; and position: relative on the button so an absolutely-positioned overlay can align to it. As always, complex animations are built by breaking them into small, single-purpose actions.
The reveals. The expanding button animates a text wrapper’s width from 0 to auto inside an overflow-hidden parent, with elastic easing for bounce, driven by toggle play/reverse on mouse-enter/leave. The fill-from-left slides a full-size overlay from translateX(-101%) to 0 while the text color changes for contrast. The fill-from-bottom does the same with a circle (aspect-ratio: 1, border-radius: 100%) sliding from translateY(100%) to 0. That -101% instead of -100% is a deliberate guard: at exactly -100%, borders or sub-pixel rounding can leave a sliver visible, so the extra 1% pushes it fully out of sight.
The tool choice — the real lesson. The fourth button (glow) uses no interaction at all. It only changes its own background, text color, and box-shadow on hover, so Webflow’s hover state plus CSS transitions handles it entirely — no GSAP, no generated JavaScript. The fifth button (light + shadow + rotating arrow) is the tell-all: the button’s scale and box-shadow are done in CSS on the hover state, but the arrow inside it can’t be, because Webflow’s hover state only styles the element itself — not its children or siblings. Rotating that child arrow needs a GSAP interaction. That boundary is the practical rule: CSS for the element’s own properties, GSAP the moment you must reach into a child. Match the easing and duration across both so the combined effect feels like one motion.
The bigger point: reaching for GSAP by default isn’t free — each interaction adds JavaScript Webflow injects into the page. Two or three hover interactions won’t sink your performance, but building consciously — CSS where it suffices, GSAP where it’s needed — keeps the site lean and your intent clear.
How to use it
-
Bouncy expanding button. Link block with an icon and an
overflow: hiddentext wrapper. One action animating the wrapper’swidth0 → auto, elastic-out easing; two hover events with control toggle play/reverse. -
Fill from the left. Button
position: relative,overflow: hidden. Add a full-size overlay (position: absolute, full offsets) attranslateX(-101%). Action 1: overlay X to0%. Action 2: text color to an off-white for contrast. Same duration, back-out easing. -
Fill from the bottom. A
divwithaspect-ratio: 1,border-radius: 100%,translateY(100%), centered via the button’s flex alignment. One action moving it totranslateY(0). -
Glow (CSS-only). Add CSS transitions on background, color, and box-shadow, then set the target values on the button’s hover state in the style panel. No interaction needed.
-
Light + shadow (hybrid). CSS transitions on
transformandbox-shadow; on the hover state, scale up and add box-shadows for the projected light and cast shadow. Then a GSAP interaction with one action rotating the child arrow (e.g. -45°), matching the CSS easing/duration so it all reads as one effect.