You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Vue3+Tailwind3中为选项切换添加挤压式CSS过渡动画?

解决液态滑动切换按钮的动画异常问题

问题背景

  • 基于Vue3 + Tailwind3开发月度/年度切换按钮,需求是点击选项时,白色背景向选中方向过渡,呈现液态挤压的流畅交互效果
  • 当前存在的问题:从Monthly切换到Yearly时动画正常,但从Yearly切回Monthly时,白色背景先向右侧偏移且无挤压效果(由scaleX:1.5导致的侧边偏移破坏效果);尝试设置transform-origin: right会引发更严重的显示异常,现有CSS方案仅能勉强运行但存在侧边截断问题

修复方案

1. 统一动画逻辑,双向复用关键帧

替换原有的两个独立动画,改为单个动画配合动态transform-origin,通过切换类来控制左右方向的动画,确保双向切换都有一致的液态挤压/舒展效果。

2. 调整容器与指示器布局

  • 确保外层容器的overflow-hidden属性生效,避免动画过程中元素溢出
  • 简化指示器的宽度计算,通过transform而非固定宽度调整位置,减少布局冲突

3. 优化动画关键帧

  • 向左切换(Yearly→Monthly)时设置transform-origin: right,向右切换(Monthly→Yearly)时设置transform-origin: left
  • 关键帧中同步控制translateX和scaleX,模拟液态挤压的自然形变过程

完整修复代码

CSS 部分

body {
  background: rgb(147 51 234);
}

/* 统一动画类,通过transform-origin控制方向 */
.animate-liquid-slide {
  animation: liquid-slide 0.6s forwards cubic-bezier(0.4, 0, 0.2, 1);
}

@keyframes liquid-slide {
  0% {
    transform: translateX(0) scaleX(1);
  }
  25% {
    transform: translateX(0) scaleX(1.3);
  }
  50% {
    transform: translateX(var(--slide-offset)) scaleX(1);
  }
  100% {
    transform: translateX(var(--slide-offset)) scaleX(1);
  }
}

HTML 部分

<script src="https://unpkg.com/petite-vue" defer init></script>
<script src="https://cdn.tailwindcss.com"></script>

<div v-scope="{ planRate: 'Yearly', prevRate: 'Yearly' }" class="flex justify-center items-center mt-8">
  <div class="flex bg-gray-200/20 rounded-full overflow-hidden relative p-1 shadow">
    <!-- 白色背景指示器 -->
    <div 
      class="absolute top-0 left-0 h-full w-1/2 p-1 transition-all"
      :class="{ 'animate-liquid-slide': planRate !== prevRate }"
      :style="{
        '--slide-offset': planRate === 'Yearly' ? '100%' : '0%',
        'transform-origin': planRate === 'Yearly' ? 'left' : 'right',
        'left': planRate === 'Yearly' ? '0' : 'auto',
        'right': planRate === 'Yearly' ? 'auto' : '0'
      }"
      @animationstart="prevRate = planRate"
    >
      <div class="w-full h-full rounded-full bg-white"></div>
    </div>

    <!-- 切换按钮 -->
    <button 
      type="button" 
      class="text-sm font-medium rounded-full py-2 px-6 relative z-10 transition-colors duration-300"
      :class="planRate === 'Monthly' ? 'text-black' : 'text-white'"
      @click="planRate = 'Monthly'"
    >
      Monthly
    </button>
    <button 
      type="button" 
      class="text-sm font-medium rounded-full py-2 px-6 relative z-10 transition-colors duration-300"
      :class="planRate === 'Yearly' ? 'text-black' : 'text-white'"
      @click="planRate = 'Yearly'"
    >
      Yearly
    </button>
  </div>
</div>

修复说明

  • 使用CSS变量--slide-offset动态控制滑动距离,配合transform-origin实现双向的挤压效果
  • 动画采用cubic-bezier曲线,让液态形变更自然
  • 通过prevRate变量触发动画,确保每次切换都能正确执行动画序列

内容的提问来源于stack exchange,提问作者tmarois

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 04:54:52