Hover✨ Premium

Icon Bounce

An icon bounces in 5 steps (translateY: 0 → -12 → -4 → -8 → 0) over 0.5s on hover — text stays still, pure CSS @keyframes.

CSSAnimation

Updated

This effect is part of Effect.Labs — 840 vanilla effects, some free, some premium. Hover has 48 effects, including 5 free. Explore the category →

3 usage examples

'Send delivery note' button — logistics validation interface — Icon Bounce example 1

① 'Send delivery note' button — logistics validation interface

WhenButton with envelope icon + label 'Send note'; on hover the icon bounces lightly, the text stays still.
WhyThe icon bounce draws attention to the action without covering the label, unlike scaling the whole button.
Settings180×48 px button; ✉️ icon at 24 px, label to the right (horizontal layout); hover area within the capture ellipse.
Cart icon in the navigation bar — header of a motorcycle-parts e-commerce site — Icon Bounce example 2

② Cart icon in the navigation bar — header of a motorcycle-parts e-commerce site

WhenCart icon in the navigation bar; on hover it bounces once, reminding the user of their cart.
WhyAn icon that bounces in a navigation header is discreet and universal — a gentle notification-like nudge without a badge.
Settings🛒 icon at 28 px, 44×44 px button; bounce centred within the navigation zone.
'Download PDF' button — catalogue for an industrial plumbing manufacturer — Icon Bounce example 3

③ 'Download PDF' button — catalogue for an industrial plumbing manufacturer

WhenButton 'Download PDF' with a downward arrow icon; the icon bounces once on hover, indicating the direction of the action (download).
WhyA downward arrow that bounces reinforces the metaphor of downloading — a universally recognised affordance.
Settings160×44 px button; ⬇ icon at 20 px + label; indigo colour; zone within the capture ellipse.

How it works

The .fx-0348-root wrapper centres a 200 px button in column layout (flex-direction: column). The icon (.ibc-icon) and label are two separate <span>s. At rest the icon is still. On hover, the ibc-bounce animation runs on the icon alone: 0.5 s, one iteration. Its five translateY steps (0 → -12 px → -4 px → -8 px → 0) produce a natural bounce — quick rise, partial rebound, second small hop, return. The text label stays fixed, unaffected.

The animation triggers on hover of the whole button, not just the icon, covering the natural hit area without depending on the cursor's exact position. :focus-visible triggers the same animation. Under reduced motion, the animation is explicitly suppressed — the icon stays still and the focus outline provides state feedback.

Accessibility

  • Reduced motion: under prefers-reduced-motion: reduce, the ibc-bounce animation is explicitly removed on hover and focus. The icon stays still. Focus state is communicated by the focus outline.
  • Keyboard: the element is a natively focusable <button>. :focus-visible triggers the icon bounce and adds a 2 px outline.
  • Icon role: the icon (aria-hidden="true") is decorative; the text label carries the semantics. Screen readers do not announce the motion.
  • Touch: on touchscreens, a tap may not trigger the :hover animation on all browsers. Functional interaction (click) does not depend on it.

Browser compatibility

Pure CSS. Properties: @keyframes, animation (1 iteration triggered on hover), :focus-visible. Verified in Chromium and Firefox: bounce visible, two independent copies, 0 errors. On browsers before 2021, :focus-visible is unavailable.

Chrome 86+✓ Full (measured)
Firefox 85+✓ Full (measured)
Safari 15.4+✓ Full (:focus-visible)
Edge 86+✓ Full (Chromium engine)
Mobile iOS 15.4+✓ Full
Android Chrome 86+✓ Full (measured)

Without :focus-visible (before 2021), keyboard focus does not trigger the bounce.

The code

HTML structure to paste into your page (the CSS + JS come with your purchase):

index.html — structure
<div class="fx-0348-root">
  <button class="ibc-box" type="button">
    <span class="ibc-icon" aria-hidden="true">🚀</span>
    <span>Your text</span>
  </button>
</div>

One-time payment, no subscription — the code is yours forever

Customize

Options passed to the API or data-* attributes:

Option / propertyDefaultEffect
Icon (HTML — .ibc-icon) 🚀 (emoji) Replace with any emoji, inline SVG, or icon font (Font Awesome, Heroicons…). Size is controlled via font-size.
Bounce height (CSS — -12px at peak) -12 px -20px for a bigger bounce; -6px for a subtle nudge. Adjust all three values consistently: 40%, 70%, 85%.
Duration (CSS — 0.5s) 0.5 s 0.3 s is snappier; 0.8 s gives a heavier, slower bounce.
Layout (CSS — flex-direction: column) icon above label Switch to flex-direction: row (icon to the left) and replace margin-bottom with margin-right on the icon.
Iteration count (CSS — animation: ... 1) once on hover Set to infinite for continuous bouncing (not recommended; mind reduced motion).

FAQ

Add a JavaScript click listener: el.addEventListener('click', () => { el.classList.remove('ibc-clicked'); void el.offsetWidth; el.classList.add('ibc-clicked'); }) and bind the animation to .ibc-clicked .ibc-icon instead of :hover.
The browser doesn't restart an animation that hasn't finished. Add a JS animationend listener on the icon that resets the animation with animation: none followed by requestAnimationFrame.
Yes. Add the .ibc-icon class to each icon. The animation applies to all elements carrying this class inside the button on hover. For staggered delays, add animation-delay to each icon individually.