HoverFree

Scale & Rotate

A box that scales up 10% and rotates 5° on hover in 0.4s — cubic-bezier with slight overshoot, violet box-shadow, pure CSS no JS.

CSSTransform

Updated

Hover or click the scene to interact

This effect is free — the Hover category contains 48 effects total, including 5 free. Effect.Labs has 840 vanilla effects. Explore the category →

Usage examples

Purchase order BC-2024-0471 In validation

Supplies order — 14 November 2026

SupplierOffice Pro Dist.
Ref.A4 80g × 10 ramettes
Qty10 boxes
Unit price€42.00 ex. VAT
Total ex. VAT€420.00

① 'Approved' stamp on a purchase order — internal tool for an office-supplies wholesaler

WhenA circular stamp centred on the order form; on hover it scales slightly and rotates 5° as if being pressed.
WhyPhysically pressing a stamp involves the same gesture — a light impact with rotation at contact. Scale alone would not convey this.
SettingsCircular element (border-radius 50%) 200 px, hover area covers 360×360 px to reach the capture ellipse; 'APPROVED' label in 20 px bold white.
Week of 11 Nov.
Tuesday lunch No idea yet? Hover the die to pick a suggestion at random

② Decision die for picking a recipe — meal-planning app for a dietitian

WhenA 200×200 px die with a dish emoji on each visible face; on hover it rotates slightly, inviting a click to randomise.
WhyRolling a die before throwing it uses the same rotation gesture, conveying the idea of chance better than scale alone.
SettingsSlightly lighter background, 48 px emoji, border-radius 12 px to suggest a real rounded die.
Artists near you 124 results
Léa Moran Lyon · Blackwork Top 2026
Tom Reyes Paris · Botanical New
Yuki Sato Bordeaux · Japanese Top 2026

③ Artist thumbnail on a tattoo marketplace — studio catalogue

WhenSquare artist photos in a grid; on hover each scales slightly and rotates 5° to stand out from the row.
WhyThe rotation breaks the grid's rigidity and draws the eye without a background animation, which a 3D tilt would require.
SettingsTen 200×200 px cards in a grid with real images; hover area covers the full card.

How it works

The .fx-0343-root wrapper (250 px tall) centres a 200 px button. On hover, transform: scale(1.1) rotate(5deg) enlarges it by 10% and rotates it 5° clockwise. The transition runs for 0.4 s using cubic-bezier(0.175, 0.885, 0.32, 1.275): fast start, slight overshoot at the end, then a ~2° elastic snap back. A violet box-shadow (rgba(99, 102, 241, 0.3)) appears at the same time, adding depth.

transition: all covers every CSS property on the element. To limit animation to only the relevant properties, replace all with transform 0.4s, box-shadow 0.4s. Pure CSS, no JavaScript. Both :hover and :focus-visible trigger the same visual, and focusability comes from the button element.

Accessibility

  • Reduced motion: under prefers-reduced-motion: reduce, all transitions are disabled and the transform is suppressed on hover — the element stays at its original size and angle. The violet box-shadow still appears instantly to signal focus or hover.
  • Keyboard: the element is a natively focusable <button>. The :focus-visible rule triggers the same scale and rotation as hover, with an indigo 2 px outline added. The rotation may be surprising: replace the target with a real link or button in your interface for clear context.
  • Touch: on touchscreens, a tap activates the CSS hover state in most mobile browsers. The effect fades when the finger lifts or focus moves elsewhere.
  • Rotation and screen readers: the rotation is purely visual. Screen readers read the element text without regard to the transform. Use a descriptive label if you adapt this effect.

Browser compatibility

Pure CSS, no dependency. Properties used: 2D transform, transition, box-shadow, cubic-bezier, :focus-visible. Verified in Chromium and Firefox: same render, elastic overshoot visible, two independent copies, 0 JS errors. :focus-visible requires Chrome 86+, Firefox 85+, Safari 15.4+ — on older versions, keyboard focus does not trigger the visual effect.

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 (browsers before 2021), keyboard focus does not trigger the visual effect — the element stays readable and clickable, the animation is absent for keyboard users only.

The code

Copy the two blocks (HTML and CSS) into your page. No JavaScript, no dependencies.

HTML
<div class="fx-0343-root">
  <button class="hover-box hover-scale-rotate" type="button">
    <span>Scale &amp; Rotate</span>
  </button>
</div>
CSS
.fx-0343-root,
.fx-0343-root *,
.fx-0343-root *::before,
.fx-0343-root *::after {
  box-sizing: border-box
}

.fx-0343-root {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 250px;
  overflow: hidden;
  position: relative;
  background: rgb(26, 26, 36);
  color: rgb(255, 255, 255);
  font-family: sans-serif;
}

/* Site design system variables this code depends on (values from css/style.css — adapt freely). */
.fx-0343-root {
  --bg-card: #12121a;
  --border: rgba(255, 255, 255, 0.08);
  --radius-xl: 1rem;
}

.fx-0343-root .hover-box {
  width: 200px;
  height: 200px;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius-xl);
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 600;
  cursor: pointer;
  position: relative;
  overflow: hidden;
  font: inherit;
  color: inherit;
  -webkit-appearance: none;
  appearance: none;
}

.fx-0343-root .hover-scale-rotate {
  transition: all 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275);
}

.fx-0343-root .hover-scale-rotate:hover {
  transform: scale(1.1) rotate(5deg);
  box-shadow: 0 20px 40px rgba(99, 102, 241, 0.3);
}

.fx-0343-root .hover-scale-rotate:focus-visible {
  transform: scale(1.1) rotate(5deg);
  box-shadow: 0 20px 40px rgba(99, 102, 241, 0.3);
  outline: 2px solid #6366f1;
  outline-offset: 3px;
}

.fx-0343-root .hover-box span {
  position: relative;
  z-index: 1;
}

@media (prefers-reduced-motion: reduce) {
  .fx-0343-root * {
    transition: none !important;
    animation-play-state: paused !important;
  }

  .fx-0343-root .hover-scale-rotate:hover,
  .fx-0343-root .hover-scale-rotate:focus-visible {
    transform: none;
  }
}
JavaScript

Pure CSS — no JavaScript needed.

Customize

Options passed to the API or data-* attributes:

Option / propertyDefaultEffect
Scale factor (CSS — scale(1.1)) 1.1 (10%) scale(1.05) is more subtle; scale(1.15) more pronounced. Above 1.2 on a 390 px screen, edges may overflow the wrapper.
Rotation angle (CSS — rotate(5deg)) 5° Positive value: clockwise; negative: anticlockwise. 0 removes the rotation, leaving only the scale.
Duration (CSS — 0.4s) 0.4 s 0.2 s is snappier; 0.6 s more relaxed. A longer duration smooths out the elastic overshoot from the curve.
Easing curve (CSS — cubic-bezier(0.175, 0.885, 0.32, 1.275)) slight overshoot ease-out removes the overshoot; cubic-bezier(0.68, -0.55, 0.265, 1.55) amplifies the spring.
Box-shadow colour (CSS — rgba(99, 102, 241, 0.3)) indigo at 30% Replace the colour to match your palette; set to 0 to remove the shadow.
Targeted transition (CSS — all) all properties Replace with transform 0.4s cubic-bezier(...), box-shadow 0.4s to limit animation to relevant properties and reduce CSS recalculation.

FAQ

How do I remove the rotation and keep only the scale?

Replace transform: scale(1.1) rotate(5deg) with transform: scale(1.1). The elastic curve stays active, giving a pure bounce effect.

The effect overflows onto neighbouring elements in my grid. How do I contain it?

Add isolation: isolate on the parent container, or overflow: hidden if you accept that the shadow is clipped. z-index: 1 on the target ensures it renders above its neighbours.

On mobile, the effect sticks after a tap. How do I fix it?

Add a JavaScript touchend listener that removes focus: el.addEventListener('touchend', () => el.blur()). On most modern mobile browsers this is enough to release the :hover state.