AI CSS Animations

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

Live from our directory: Icon Slide Button. Copy the HTML and CSS →

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.

Adam Wathan's Tailwind version ↗

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.

4. Magic UI Interactive Hover Button: Best for landing page CTAs in a shadcn-style React stack

Platform: React + Tailwind, MIT, installs with the shadcn CLI

Live from our directory: Dot Expand Button. Copy the HTML and CSS →

Magic UI's version is the flood fill. An 8px dot (h-2 w-2) sits left of the label. On hover it scales up about a hundred times (scale-[100.8] in the source) until it fills the pill, the label slides right and fades out, and a second copy of the label with an arrow slides in on top in the foreground colour. All three moves share one 300ms transition.

It works because the dot is a real element grown with transform, which browsers can animate cheaply, and because the arrow arrives with the fill, so the change of colour and the change of meaning land at the same moment.

Our Dot Expand Button below is a pure-CSS version of the same idea with no React: the dot scales 44 times over 0.55s and the label slides back to the true centre once the dot has gone.

Watch out for: The label is in the markup twice and the second copy has no aria-hidden, so screen readers can announce it twice. Add aria-hidden to the copy if you install it.

Source on GitHub ↗

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

Live from our directory: Float Shadow Hover Effect. Copy the HTML and CSS →

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).

GitHub ↗

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)

Live from our directory: Slide Fill Button. Copy the HTML and CSS →

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.

7. Codrops Button Styles Inspiration: Best for agency and studio sites that want a signature CTA

Platform: HTML + CSS, Codrops licence (free in personal and commercial work)

Live from our directory: Skew Fill Button. Copy the HTML and CSS →

Codrops' 2015 set is still one of the best catalogues of button fills, and each style has a name instead of a number: Winona, Ujarak, Wayra, Tamaya, Moema, Aylen, Saqui, Nuka, Antiman, Itzel, Naira, Shikoba and more. They are built from pseudo-elements and CSS transitions, with an icon font for the icon variants.

Wayra shows the craft. A pseudo-element 150% as wide as the button starts rotated minus 45 degrees off one corner and swings flat on hover, while the border and text colour follow over 0.3s on cubic-bezier(0.2, 1, 0.3, 1), a fast start with a long soft landing. Our Skew Fill Button below is a pure-CSS cousin: a panel skewed 20 degrees wipes across in 0.35s.

Pick from this set when one button carries the page, like the contact button on a studio site, and you want it to feel designed rather than default.

Watch out for: The licence lets you build on the code in your own projects but not republish or sell it as-is. The CSS dates from 2015, so strip the -webkit- prefixes and swap the icon font for inline SVG.

Codrops Creative Button Styles (2013) ↗

8. Codrops Magnetic Buttons: Best for creative portfolios with a custom cursor

Platform: JavaScript + GSAP 3, MIT

Live from our directory: Magnetic Button Hover Effect. Copy the HTML and CSS →

Codrops' 2020 Magnetic Buttons, inspired by the buttons on Cuberto, pull toward the cursor before you reach them. The code is short. A requestAnimationFrame loop measures the distance from the pointer to the button's centre; once it is under 70% of the button's width, the button moves 30% of the way toward the pointer and the label moves the opposite way at 0.6 times that, which gives it depth. Each frame closes 10% of the remaining gap, so the motion glides instead of snapping, and GSAP animates the label when the pointer enters.

Magnetic buttons reward the approach, not just the arrival. On a portfolio with a big custom cursor, they make the page feel physical.

If you want the feel without JavaScript, our Magnetic Button Hover Effect below fakes it with nine invisible cells around the pill. Each cell sets --x and --y through sibling selectors, so the button leans toward the pointer in nine steps.

Watch out for: The loop runs every frame for every button, even when the cursor is nowhere near. Stop it when the button is off-screen, skip it for touch and coarse pointers, and turn it off under prefers-reduced-motion.

Cuberto, the inspiration ↗

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.

10. Uiverse community buttons: Best for browsing hundreds of takes before you build your own

Platform: Community library, CSS or Tailwind, MIT

Live from our directory: Neon Button. Copy the HTML and CSS →

Uiverse is an open-source library of community-made UI elements, more than 3,000 of them by its own count, in plain CSS or Tailwind and released under MIT. Buttons have their own section, and its GitHub archive holds over a thousand button files, each named with its creator's username.

It is the fastest way to see twenty variations of one idea side by side. Use it to find the shape you want, then rebuild it to your own standards. Uiverse asks, but does not require, that you credit both the creator and the site.

For the glowing outline look many people come here for, our Neon Button below is a pure-CSS version: the border and label glow with stacked box-shadows and a text-shadow over 0.3s, built for dark backgrounds.

Watch out for: Quality varies from author to author. Before you paste one in, check it uses a real button element, has a visible focus state and respects prefers-reduced-motion; community snippets do not always include all three.

Uiverse on GitHub ↗

11. Our Button Hover Effects collection: Best for copying a tested CSS hover into any stack

Platform: Motions directory, free, HTML + CSS Ours

Live from our directory: Shine Sweep Button. Copy the HTML and CSS →

Our Button Hover Effects collection pulls together the button hovers in our directory: fills, sweeps, borders that draw themselves, glows, lifts and text swaps. Each one is HTML and CSS with no JavaScript, a prefers-reduced-motion guard, and two custom properties for colour and size, so it drops into React, Svelte, Webflow or a plain HTML page.

The demo below is Shine Sweep Button: a translucent band at 120 degrees crosses the button in 0.6s, like light moving across glass. The band moves with transform, so it stays cheap even on slow phones.

For the rest of the family, browse the full Hover Effects and Buttons directories. If none of them fit, describe the one you want to the creator and it writes the keyframes for you.

Watch out for: Shine Sweep plays only on hover, so touch users never see it. That is fine for decoration, but never put information behind a hover.

12. Our Rotating Gradient Border Button: Best for one premium CTA on a dark landing page

Platform: Motions directory, free, pure CSS with @property Ours

Live from our directory: Rotating Gradient Border Button. Copy the HTML and CSS →

A dark button sits inside a 2px conic-gradient ring. On hover or keyboard focus the ring starts to turn, one lap every 2.4s, and a blurred copy of it fades in behind, so the button glows in moving colour. The angle is a registered @property, which is what lets the gradient rotate smoothly instead of jumping from one frame to the next.

It is a hover that says "this is the important one" without changing size or position, so the layout around it stays still. For more rings, beams and drawn outlines, see the Border Animations directory and our border animation examples.

Watch out for: Rotating a gradient and blurring it repaints every frame while hovered. Keep it to one button per screen. Browsers without @property support show a still ring, which is a fine fallback.

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.

A prompt to start from
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.

Make your own with AI →

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