Guides · · Maxwell Prehoda
12 Button Hover Effect Examples From Real Sites, With the Timings They Actually Use
The best button hover effects are small and fast. Stripe slides a 6px arrow over 0.3s, Linear brightens the whole button in 0.1s, and the default shadcn/ui button only fades its fill to 90%. Big fills, glows and magnetic pulls work too, but they belong on the one button you most want clicked, not on every button in the interface.
Below are 12 examples: real products, open-source libraries and Codrops classics, each with the numbers from its shipped CSS or source code (checked in November 2026), what it is best for, and the trap to avoid. Most come with a live pure-CSS demo from our free directory that you can copy.
1. Stripe's hover arrow: Best for text links and secondary CTAs that lead somewhere
Platform: Website (stripe.com), inline SVG + one CSS custom property
Hover a button or link on stripe.com and the small chevron after the label grows a shaft and slides right, turning into an arrow. The SVG holds two parts: the chevron, and a thin bar parked to its left at zero opacity. One custom property, --hds-hover-active, flips from 0 to 1 when the button is hovered, and two rules read it: the bar fades in, and the arrow group moves calc(var(--hds-hover-active) * 6px) to the right.
Both moves take 0.3s on cubic-bezier(.25, 1, .5, 1), a strong ease-out that starts fast and settles gently, and the selector skips disabled buttons. It is probably the most copied hover on the web because it says "this goes somewhere" without moving the button itself. Adam Wathan published a Tailwind recreation built the same way, with the two paths in one SVG and group variants.
Our Icon Slide Button below is the simplest pure-CSS version of the idea: the arrow nudges 0.3em to the right on hover, with no shaft to draw.
Watch out for: The rule we found listens to :hover only. If you copy it, add :focus-visible to the same selector so keyboard users get the cue too, since the arrow is what tells people the link leads on.
2. Linear's brightness hover: Best for dark interfaces with many tinted button colours
Platform: Website (linear.app), CSS filter
Linear's site rarely picks a separate hover colour. Its stylesheet brightens controls with filter: brightness() instead. One shared style for links and buttons goes to brightness(1.3) on hover and brightness(1.6) while pressed, and smaller controls such as its send buttons transition filter over 0.16s.
The timing is asymmetric. The base rule transitions filter over 0.2s, and the hover rule shortens that to 0.1s, so the button lights up quickly and dims slowly when the pointer leaves. Fast in, slow out is the single most useful hover trick on this list: it feels responsive without flickering when the cursor skims across a toolbar.
Pick this when you have a palette of coloured buttons and do not want to hand-pick a hover shade for each. One rule covers every colour, including ones your designers add next year.
Watch out for: Brightness does nothing to pure white and washes out light colours, and it brightens the label along with the fill. Check the contrast of the hovered state, not just the resting one.
3. shadcn/ui's 90% fade: Best for React apps built on shadcn/ui and Tailwind
Platform: React + Tailwind CSS, MIT, copied into your project
The default shadcn/ui button barely moves on hover, on purpose. In the component source, the primary variant uses hover:bg-primary/90, the outline and ghost variants swap to the accent background, and transition-all animates the change on Tailwind's defaults of 150ms and cubic-bezier(0.4, 0, 0.2, 1). The focus state gets more design than the hover: a 3px ring on focus-visible.
Because so many products start from this file, it is the baseline your users already know. If your hover is louder than this, it should be because that button matters more, not because loud is the default.
One small fix worth making when you add motion of your own: swap transition-all for transition-colors plus the specific properties you animate. transition-all animates anything that changes, including properties you never meant to animate.
Watch out for: A 10% change in opacity on a dark primary colour can be nearly invisible, especially on cheap screens. Test the hover on the real palette, and never let it be the only sign that something is clickable.
5. Hover.css by Ian Lunn: Best for trying named classic effects on existing buttons
Platform: CSS, Sass or LESS; MIT for open source, paid commercial licence
Hover.css is the reference library for classic hover effects, and its names are still how people search for them: Grow, Pulse, Float Shadow, Sweep To Right, Radial Out, Shutter In Horizontal, Icon Spin, Underline From Left, Curl Top Left. Each effect is one class on one element, with pseudo-elements where it needs an extra layer, and the library ships as CSS, Sass and LESS.
Float Shadow is the one that has aged best. The button rises while a soft shadow stays on the ground, so it reads as lifting off the page rather than sliding up it. Our Float Shadow Hover Effect below is our own pure-CSS take under the same name: the button moves up 0.5em while a radial-gradient shadow drops and narrows beneath it.
Pick Hover.css when you want a vocabulary of effects to try on a page quickly. Copy the two or three classes you settle on rather than shipping the whole file.
Watch out for: The licence changed in 2017. MIT covers personal and open-source projects, but selling an app that uses it needs a commercial licence ($14 for one project or $18 for unlimited when we checked).
6. Temani Afif's background fills on CSS-Tricks: Best for fills that need no extra elements at all
Platform: Pure CSS, CSS-Tricks article (April 2022)
Temani Afif builds sweeping fills from a single-colour gradient, linear-gradient(#1095c1 0 0), animated through background-size and background-position. Grow the size from 0 to 100% and colour wipes across the element. Start it as a thin .08em strip at the bottom and it reads as an underline that floods up into a full highlight.
The detail worth stealing is the exit. He changes background-position instantly on hover and animates only the size, so the fill leaves from the side opposite to where it came in, which looks deliberate instead of rewound. He also reduces each effect to one custom property that acts as an on and off switch, which keeps the CSS tiny.
Our Slide Fill Button below gets the same left-to-right fill with a pseudo-element moved by transform instead of a background, which is the cheaper route when many buttons on a page animate.
Watch out for: Animating background-size and background-position repaints on every frame, and a reader comment on the article reports lag in Safari. One button is fine; a grid of them is where a transformed pseudo-element wins.
9. Material Design state layers: Best for design systems that need one hover rule everywhere
Platform: Material Web (Lit web components), Apache 2.0
Material does not really animate hover. It lays a translucent state layer over the component in the content colour. In the Material Web token source, that layer is 8% opacity for hover, 12% for focus, 12% for pressed and 16% for dragged. The md-ripple element draws both the hover layer and the press ripple.
The hover layer fades in over 15ms linear in Material Web's ripple styles, which is effectively instant. That is the point: in a dense app, hover is information about what you are about to click, not a show.
Steal the idea even if you never use Material. One pseudo-element in currentColor at 8% opacity gives every button, chip and list row the same hover in both light and dark themes, with no hover colour to design per component.
Watch out for: An 8% layer is easy to miss on saturated fills and over images. Material pairs it with a visible focus ring and a press ripple, so do not ship the hover layer on its own.
How to choose a button hover effect
Three questions settle it: what the button does, what the person is holding, and how much motion the page can afford.
Match it to the button's job
Rank your buttons. The everyday ones, in toolbars, tables and forms, want the quiet treatments: a colour shift like shadcn/ui, a brightness lift like Linear, or an 8% state layer like Material. Links that lead somewhere want a direction cue like Stripe's arrow. Only the one or two buttons that carry the page earn a fill, a glow, a rotating border or a magnetic pull. If every button on a screen sweeps and glows, none of them stands out.
Match it to the input
Hover only exists for a mouse or trackpad. On phones, a tap can leave a hover style stuck on until the next tap, so wrap decorative hovers in @media (hover: hover) and (pointer: fine). Put the same styles on :focus-visible so keyboard users see them, and give the button its own press feedback, which is a separate job covered in our button click animation examples. Under prefers-reduced-motion, keep the colour change and drop the movement.
Match it to your performance budget
Transform and opacity animate on the compositor and stay smooth on slow phones; that is why the Slide Fill Button and Magic UI's dot use transform. Background-size, box-shadow, filter and blur repaint on each frame, which is fine for one button and costly for a grid. Keep durations between about 100ms and 300ms, and make the way in faster than the way out, the way Linear does with 0.1s in and 0.2s out.
Pick one and ship it today
Start with the quiet version for every button: a colour or brightness change in under 150ms, mirrored on focus-visible. Then choose a single signature hover for your main call to action from the list above, copy it from our Button Hover Effects collection, and set its colour with the custom property.
If you want something nobody else has, describe it to the creator. It asks a few quick questions while it works and hands back production-ready CSS keyframes with a reduced-motion fallback.
Make a hover effect for the primary call-to-action button on a dark SaaS landing page. On hover and on keyboard focus, a fill sweeps in from the left and a small arrow after the label slides 6px to the right. Ease in over 180ms with cubic-bezier(0.25, 1, 0.5, 1); ease out over 300ms. Animate only transform and opacity, and apply it only when (hover: hover) and (pointer: fine). Under prefers-reduced-motion, keep the colour change and remove all movement.
Common questions
What makes a good button hover effect?
It is quick, it confirms that the thing is clickable, and it never changes the button's size or the layout around it. Most real products use a simple colour, brightness or opacity change, with a richer effect saved for the main call to action.
How long should a button hover animation be?
Roughly 100ms to 300ms. The examples here range from Material Web's 15ms hover layer and shadcn/ui's 150ms to Stripe's 0.3s arrow. Making the way in faster than the way out, as Linear does with 0.1s in and 0.2s out, feels responsive without flickering.
Do button hover effects work on mobile?
No. Touch screens have no hover, and a tap can leave a hover style stuck on. Wrap decorative hovers in @media (hover: hover) and (pointer: fine), and give touch users press feedback with :active instead.
How do I make a button hover effect with CSS only?
Put a transition on the button, then change properties in :hover and :focus-visible. For fills and sweeps, animate a pseudo-element with transform rather than animating the background, and add a prefers-reduced-motion block that removes the movement. Every snippet in our Hover Effects directory follows that pattern.
Should hover effects respect prefers-reduced-motion?
Yes. Keep the colour or opacity change, since that carries the information, and drop the sliding, scaling and spinning. Magnetic and rotating effects should switch off completely.
Sources
- Stripe homepage and its shipped button CSS
- Adam Wathan: Recreating Stripe's arrow animation
- Linear homepage and its shipped CSS
- shadcn/ui button source
- Tailwind CSS: transition-property defaults
- Magic UI: Interactive Hover Button
- Hover.css by Ian Lunn
- Temani Afif, CSS-Tricks: Cool Hover Effects That Use Background Properties
- Codrops Button Styles Inspiration source
- Codrops Magnetic Buttons source
- Material Web: Ripple
- Material Web state tokens
- Uiverse galaxy archive