Flip Button

A button that flips over on hover to reveal its back face.

<script setup lang="ts">
import type { FlipDirection } from '@/components/animate-ui/buttons/flip/context'
import FlipButton from '@/components/animate-ui/buttons/flip/FlipButton.vue'
import FlipButtonBack from '@/components/animate-ui/buttons/flip/FlipButtonBack.vue'
import FlipButtonFront from '@/components/animate-ui/buttons/flip/FlipButtonFront.vue'

withDefaults(defineProps<{ from?: FlipDirection, tapScale?: number | string }>(), {
  from: 'top',
  tapScale: 0.97,
})
</script>

<template>
  <FlipButton :from="from" :tap-scale="Number(tapScale)">
    <FlipButtonFront>
      Front
    </FlipButtonFront>
    <FlipButtonBack>
      Back Button
    </FlipButtonBack>
  </FlipButton>
</template>

Installation

npx shadcn-vue@latest add https://animate-ui.com/r/vue/buttons-flip.json
pnpm dlx shadcn-vue@latest add https://animate-ui.com/r/vue/buttons-flip.json
yarn dlx shadcn-vue@latest add https://animate-ui.com/r/vue/buttons-flip.json
bun x shadcn-vue@latest add https://animate-ui.com/r/vue/buttons-flip.json

Usage

<script setup lang="ts">
import FlipButton from '@/components/animate-ui/buttons/flip/FlipButton.vue';
import FlipButtonBack from '@/components/animate-ui/buttons/flip/FlipButtonBack.vue';
import FlipButtonFront from '@/components/animate-ui/buttons/flip/FlipButtonFront.vue';
</script>

<template>
  <FlipButton from="top">
    <FlipButtonFront>Subscribe</FlipButtonFront>
    <FlipButtonBack>It's free</FlipButtonBack>
  </FlipButton>
</template>

Animation

  • On hover, the front face rotates away (90°, sliding half its height or width) and fades out while the back face rotates in from from, on a bouncy spring (stiffness: 280, damping: 20) that swings past the end before settling. Leaving flips it back.
  • The faces are stacked in the same grid cell: the button takes the size of the larger one.
  • Pressing scales the button to tap-scale on Motion's spring for scale (stiffness: 550, damping: 30).
  • <AnimateUIProvider :tempo> paces the default springs.
  • Under reduced motion, the faces crossfade without rotating or sliding, and the button doesn't scale.

API Reference

FlipButton

PropTypeDefault
from?
'top' | 'bottom' | 'left' | 'right''top'
tap-scale?
number0.97
transition?
Transition{ type: 'spring', stiffness: 550, damping: 30, restSpeed: 10 }
as-child?
booleanfalse
...props?
HTMLMotionProps<'button'>-

FlipButtonFront

PropTypeDefault
transition?
Transition{ type: 'spring', stiffness: 280, damping: 20 }
as-child?
booleanfalse
...props?
HTMLMotionProps<'span'>-

FlipButtonBack

PropTypeDefault
transition?
Transition{ type: 'spring', stiffness: 280, damping: 20 }
as-child?
booleanfalse
...props?
HTMLMotionProps<'span'>-

useFlipButton

Returns { from, isVertical, rotateAxis } inside a FlipButton.

Built by Skyleen. The source code is available on GitHub.

Last updated: 10/23/2026